From 61bfe2d70cae6be8c4086a210a5451135ccca9ea Mon Sep 17 00:00:00 2001 From: Magnus Auvinen Date: Sat, 2 Aug 2008 08:21:29 +0000 Subject: added doc tool --- docs/tool/Modules/NaturalDocs/BinaryFile.pm | 294 ++ docs/tool/Modules/NaturalDocs/Builder.pm | 280 ++ docs/tool/Modules/NaturalDocs/Builder/Base.pm | 348 ++ .../tool/Modules/NaturalDocs/Builder/FramedHTML.pm | 345 ++ docs/tool/Modules/NaturalDocs/Builder/HTML.pm | 398 +++ docs/tool/Modules/NaturalDocs/Builder/HTMLBase.pm | 3693 ++++++++++++++++++++ docs/tool/Modules/NaturalDocs/ClassHierarchy.pm | 860 +++++ .../Modules/NaturalDocs/ClassHierarchy/Class.pm | 412 +++ .../Modules/NaturalDocs/ClassHierarchy/File.pm | 157 + docs/tool/Modules/NaturalDocs/ConfigFile.pm | 497 +++ docs/tool/Modules/NaturalDocs/Constants.pm | 165 + docs/tool/Modules/NaturalDocs/DefineMembers.pm | 100 + docs/tool/Modules/NaturalDocs/Error.pm | 305 ++ docs/tool/Modules/NaturalDocs/File.pm | 540 +++ .../Modules/NaturalDocs/ImageReferenceTable.pm | 383 ++ .../NaturalDocs/ImageReferenceTable/Reference.pm | 44 + .../NaturalDocs/ImageReferenceTable/String.pm | 110 + docs/tool/Modules/NaturalDocs/Languages.pm | 1475 ++++++++ .../Modules/NaturalDocs/Languages/ActionScript.pm | 1473 ++++++++ docs/tool/Modules/NaturalDocs/Languages/Ada.pm | 38 + .../tool/Modules/NaturalDocs/Languages/Advanced.pm | 828 +++++ .../NaturalDocs/Languages/Advanced/Scope.pm | 95 + .../NaturalDocs/Languages/Advanced/ScopeChange.pm | 70 + docs/tool/Modules/NaturalDocs/Languages/Base.pm | 832 +++++ docs/tool/Modules/NaturalDocs/Languages/CSharp.pm | 1484 ++++++++ docs/tool/Modules/NaturalDocs/Languages/PLSQL.pm | 319 ++ docs/tool/Modules/NaturalDocs/Languages/Pascal.pm | 143 + docs/tool/Modules/NaturalDocs/Languages/Perl.pm | 1370 ++++++++ .../Modules/NaturalDocs/Languages/Prototype.pm | 92 + .../NaturalDocs/Languages/Prototype/Parameter.pm | 87 + docs/tool/Modules/NaturalDocs/Languages/Simple.pm | 503 +++ docs/tool/Modules/NaturalDocs/Languages/Tcl.pm | 219 ++ docs/tool/Modules/NaturalDocs/Menu.pm | 3406 ++++++++++++++++++ docs/tool/Modules/NaturalDocs/Menu/Entry.pm | 201 ++ docs/tool/Modules/NaturalDocs/NDMarkup.pm | 76 + docs/tool/Modules/NaturalDocs/Parser.pm | 1331 +++++++ docs/tool/Modules/NaturalDocs/Parser/JavaDoc.pm | 464 +++ docs/tool/Modules/NaturalDocs/Parser/Native.pm | 1060 ++++++ .../tool/Modules/NaturalDocs/Parser/ParsedTopic.pm | 253 ++ docs/tool/Modules/NaturalDocs/Project.pm | 1402 ++++++++ docs/tool/Modules/NaturalDocs/Project/ImageFile.pm | 160 + .../tool/Modules/NaturalDocs/Project/SourceFile.pm | 113 + docs/tool/Modules/NaturalDocs/ReferenceString.pm | 334 ++ docs/tool/Modules/NaturalDocs/Settings.pm | 1418 ++++++++ .../Modules/NaturalDocs/Settings/BuildTarget.pm | 66 + docs/tool/Modules/NaturalDocs/SourceDB.pm | 678 ++++ .../tool/Modules/NaturalDocs/SourceDB/Extension.pm | 84 + docs/tool/Modules/NaturalDocs/SourceDB/File.pm | 129 + docs/tool/Modules/NaturalDocs/SourceDB/Item.pm | 201 ++ .../Modules/NaturalDocs/SourceDB/ItemDefinition.pm | 45 + .../NaturalDocs/SourceDB/WatchedFileDefinitions.pm | 159 + docs/tool/Modules/NaturalDocs/StatusMessage.pm | 102 + docs/tool/Modules/NaturalDocs/SymbolString.pm | 212 ++ docs/tool/Modules/NaturalDocs/SymbolTable.pm | 1984 +++++++++++ docs/tool/Modules/NaturalDocs/SymbolTable/File.pm | 186 + .../NaturalDocs/SymbolTable/IndexElement.pm | 522 +++ .../Modules/NaturalDocs/SymbolTable/Reference.pm | 273 ++ .../NaturalDocs/SymbolTable/ReferenceTarget.pm | 97 + .../tool/Modules/NaturalDocs/SymbolTable/Symbol.pm | 428 +++ .../NaturalDocs/SymbolTable/SymbolDefinition.pm | 96 + docs/tool/Modules/NaturalDocs/Topics.pm | 1319 +++++++ docs/tool/Modules/NaturalDocs/Topics/Type.pm | 151 + docs/tool/Modules/NaturalDocs/Version.pm | 384 ++ 63 files changed, 35293 insertions(+) create mode 100644 docs/tool/Modules/NaturalDocs/BinaryFile.pm create mode 100644 docs/tool/Modules/NaturalDocs/Builder.pm create mode 100644 docs/tool/Modules/NaturalDocs/Builder/Base.pm create mode 100644 docs/tool/Modules/NaturalDocs/Builder/FramedHTML.pm create mode 100644 docs/tool/Modules/NaturalDocs/Builder/HTML.pm create mode 100644 docs/tool/Modules/NaturalDocs/Builder/HTMLBase.pm create mode 100644 docs/tool/Modules/NaturalDocs/ClassHierarchy.pm create mode 100644 docs/tool/Modules/NaturalDocs/ClassHierarchy/Class.pm create mode 100644 docs/tool/Modules/NaturalDocs/ClassHierarchy/File.pm create mode 100644 docs/tool/Modules/NaturalDocs/ConfigFile.pm create mode 100644 docs/tool/Modules/NaturalDocs/Constants.pm create mode 100644 docs/tool/Modules/NaturalDocs/DefineMembers.pm create mode 100644 docs/tool/Modules/NaturalDocs/Error.pm create mode 100644 docs/tool/Modules/NaturalDocs/File.pm create mode 100644 docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm create mode 100644 docs/tool/Modules/NaturalDocs/ImageReferenceTable/Reference.pm create mode 100644 docs/tool/Modules/NaturalDocs/ImageReferenceTable/String.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/ActionScript.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Ada.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Advanced.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Advanced/Scope.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Base.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/CSharp.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/PLSQL.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Pascal.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Perl.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Prototype.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Prototype/Parameter.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Simple.pm create mode 100644 docs/tool/Modules/NaturalDocs/Languages/Tcl.pm create mode 100644 docs/tool/Modules/NaturalDocs/Menu.pm create mode 100644 docs/tool/Modules/NaturalDocs/Menu/Entry.pm create mode 100644 docs/tool/Modules/NaturalDocs/NDMarkup.pm create mode 100644 docs/tool/Modules/NaturalDocs/Parser.pm create mode 100644 docs/tool/Modules/NaturalDocs/Parser/JavaDoc.pm create mode 100644 docs/tool/Modules/NaturalDocs/Parser/Native.pm create mode 100644 docs/tool/Modules/NaturalDocs/Parser/ParsedTopic.pm create mode 100644 docs/tool/Modules/NaturalDocs/Project.pm create mode 100644 docs/tool/Modules/NaturalDocs/Project/ImageFile.pm create mode 100644 docs/tool/Modules/NaturalDocs/Project/SourceFile.pm create mode 100644 docs/tool/Modules/NaturalDocs/ReferenceString.pm create mode 100644 docs/tool/Modules/NaturalDocs/Settings.pm create mode 100644 docs/tool/Modules/NaturalDocs/Settings/BuildTarget.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB/Extension.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB/File.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB/Item.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB/ItemDefinition.pm create mode 100644 docs/tool/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm create mode 100644 docs/tool/Modules/NaturalDocs/StatusMessage.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolString.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/File.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/IndexElement.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/Reference.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/Symbol.pm create mode 100644 docs/tool/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm create mode 100644 docs/tool/Modules/NaturalDocs/Topics.pm create mode 100644 docs/tool/Modules/NaturalDocs/Topics/Type.pm create mode 100644 docs/tool/Modules/NaturalDocs/Version.pm (limited to 'docs/tool/Modules/NaturalDocs') diff --git a/docs/tool/Modules/NaturalDocs/BinaryFile.pm b/docs/tool/Modules/NaturalDocs/BinaryFile.pm new file mode 100644 index 00000000..5c1adb8d --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/BinaryFile.pm @@ -0,0 +1,294 @@ +############################################################################### +# +# Package: NaturalDocs::BinaryFile +# +############################################################################### +# +# A package to manage Natural Docs' binary data files. +# +# Usage: +# +# - Only one data file can be managed with this package at a time. You must close the file before opening another +# one. +# +############################################################################### + +# 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; + +package NaturalDocs::BinaryFile; + +use vars qw(@EXPORT @ISA); +require Exporter; +@ISA = qw(Exporter); + +@EXPORT = ('BINARY_FORMAT'); + + +############################################################################### +# Group: Format + +# +# Topic: Standard Header +# +# > [UInt8: BINARY_FORMAT] +# > [VersionInt: app version] +# +# The first byte is , which distinguishes binary configuration files from text ones, since Natural Docs +# used to use text data files with the same name. +# +# The next section is the version of Natural Docs that wrote the file, as defined by AppVersion> +# and written by ToBinaryFile()>. +# + +# +# Topic: Data Types +# +# All the integer data types are written most significant byte first, aka big endian. +# +# An AString16 is a UInt16 followed by that many 8-bit ASCII characters. It doesn't include a null character at the end. Undef +# strings are represented by a zero for the UInt16 and nothing following it. +# + +# +# Constant: BINARY_FORMAT +# +# An 8-bit constant that's used as the first byte of binary data files. This is used so that you can easily distinguish between +# binary and old-style text data files. It's not a character that would appear in plain text files. +# +use constant BINARY_FORMAT => pack('C', 0x06); +# Which is ACK or acknowledge in ASCII. Is the cool spade character in DOS displays. + + +############################################################################### +# Group: Variables + +# +# handle: FH_BINARYDATAFILE +# +# The file handle used for the data file. +# + + +# +# string: currentFile +# +# The for the current configuration file being parsed. +# +my $currentFile; + + + +############################################################################### +# Group: File Functions + + +# +# Function: OpenForReading +# +# Opens a binary file for reading. +# +# Parameters: +# +# minimumVersion - The minimum version of the file format that is acceptible. May be undef. +# +# Returns: +# +# The format or undef if it failed. It could fail for any of the following reasons. +# +# - The file doesn't exist. +# - The file couldn't be opened. +# - The file didn't have the proper header. +# - Either the application or the file was from a development release, and they're not the exact same development release. +# - The file's format was less than the minimum version, if one was defined. +# - The file was from a later application version than the current. +# +sub OpenForReading #(FileName file, optional VersionInt minimumVersion) => VersionInt + { + my ($self, $file, $minimumVersion) = @_; + + if (defined $currentFile) + { die "Tried to open binary file " . $file . " for reading when " . $currentFile . " was already open."; }; + + $currentFile = $file; + + if (open(FH_BINARYDATAFILE, '<' . $currentFile)) + { + # See if it's binary. + binmode(FH_BINARYDATAFILE); + + my $firstChar; + read(FH_BINARYDATAFILE, $firstChar, 1); + + if ($firstChar == ::BINARY_FORMAT()) + { + my $version = NaturalDocs::Version->FromBinaryFile(\*FH_BINARYDATAFILE); + + if (NaturalDocs::Version->CheckFileFormat($version, $minimumVersion)) + { return $version; }; + }; + + close(FH_BINARYDATAFILE); + }; + + $currentFile = undef; + return undef; + }; + + +# +# Function: OpenForWriting +# +# Opens a binary file for writing and writes the standard header. Dies if the file cannot be opened. +# +sub OpenForWriting #(FileName file) + { + my ($self, $file) = @_; + + if (defined $currentFile) + { die "Tried to open binary file " . $file . " for writing when " . $currentFile . " was already open."; }; + + $currentFile = $file; + + open (FH_BINARYDATAFILE, '>' . $currentFile) + or die "Couldn't save " . $file . ".\n"; + + binmode(FH_BINARYDATAFILE); + + print FH_BINARYDATAFILE '' . ::BINARY_FORMAT(); + NaturalDocs::Version->ToBinaryFile(\*FH_BINARYDATAFILE, NaturalDocs::Settings->AppVersion()); + }; + + +# +# Function: Close +# +# Closes the current configuration file. +# +sub Close + { + my $self = shift; + + if (!$currentFile) + { die "Tried to close a binary file when one wasn't open."; }; + + close(FH_BINARYDATAFILE); + $currentFile = undef; + }; + + + +############################################################################### +# Group: Reading Functions + + +# +# Function: GetUInt8 +# Reads and returns a UInt8 from the open file. +# +sub GetUInt8 # => UInt8 + { + my $raw; + read(FH_BINARYDATAFILE, $raw, 1); + + return unpack('C', $raw); + }; + +# +# Function: GetUInt16 +# Reads and returns a UInt16 from the open file. +# +sub GetUInt16 # => UInt16 + { + my $raw; + read(FH_BINARYDATAFILE, $raw, 2); + + return unpack('n', $raw); + }; + +# +# Function: GetUInt32 +# Reads and returns a UInt32 from the open file. +# +sub GetUInt32 # => UInt32 + { + my $raw; + read(FH_BINARYDATAFILE, $raw, 4); + + return unpack('N', $raw); + }; + +# +# Function: GetAString16 +# Reads and returns an AString16 from the open file. Supports undef strings. +# +sub GetAString16 # => string + { + my $rawLength; + read(FH_BINARYDATAFILE, $rawLength, 2); + my $length = unpack('n', $rawLength); + + if (!$length) + { return undef; }; + + my $string; + read(FH_BINARYDATAFILE, $string, $length); + + return $string; + }; + + + +############################################################################### +# Group: Writing Functions + + +# +# Function: WriteUInt8 +# Writes a UInt8 to the open file. +# +sub WriteUInt8 #(UInt8 value) + { + my ($self, $value) = @_; + print FH_BINARYDATAFILE pack('C', $value); + }; + +# +# Function: WriteUInt16 +# Writes a UInt32 to the open file. +# +sub WriteUInt16 #(UInt16 value) + { + my ($self, $value) = @_; + print FH_BINARYDATAFILE pack('n', $value); + }; + +# +# Function: WriteUInt32 +# Writes a UInt32 to the open file. +# +sub WriteUInt32 #(UInt32 value) + { + my ($self, $value) = @_; + print FH_BINARYDATAFILE pack('N', $value); + }; + +# +# Function: WriteAString16 +# Writes an AString16 to the open file. Supports undef strings. +# +sub WriteAString16 #(string value) + { + my ($self, $string) = @_; + + if (length($string)) + { print FH_BINARYDATAFILE pack('nA*', length($string), $string); } + else + { print FH_BINARYDATAFILE pack('n', 0); }; + }; + + +1; diff --git a/docs/tool/Modules/NaturalDocs/Builder.pm b/docs/tool/Modules/NaturalDocs/Builder.pm new file mode 100644 index 00000000..cdcdff72 --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/Builder.pm @@ -0,0 +1,280 @@ +############################################################################### +# +# Package: NaturalDocs::Builder +# +############################################################################### +# +# A package that takes parsed source file and builds the output for it. +# +# Usage and Dependencies: +# +# - can be called immediately. +# - and can be called once all sub-packages have been registered via . +# Since this is normally done in their INIT functions, they should be available to all normal functions immediately. +# +# - Prior to calling , , , , and +# must be initialized. GenerateDirectoryNames()> must be called. +# and 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 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->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->BuildTargets(); + + my $filesToBuild = NaturalDocs::Project->FilesToBuild(); + my $numberOfFilesToBuild = (scalar keys %$filesToBuild) * (scalar @$buildTargets); + + my $filesToPurge = NaturalDocs::Project->FilesToPurge(); + my $numberOfFilesToPurge = (scalar keys %$filesToPurge) * (scalar @$buildTargets); + + my $imagesToUpdate = NaturalDocs::Project->ImageFilesToUpdate(); + my $numberOfImagesToUpdate = (scalar keys %$imagesToUpdate) * (scalar @$buildTargets); + + my $imagesToPurge = NaturalDocs::Project->ImageFilesToPurge(); + my $numberOfImagesToPurge = (scalar keys %$imagesToPurge) * (scalar @$buildTargets); + + my %indexesToBuild; + my %indexesToPurge; + + my $currentIndexes = NaturalDocs::Menu->Indexes(); + my $previousIndexes = NaturalDocs::Menu->PreviousIndexes(); + + foreach my $index (keys %$currentIndexes) + { + if (NaturalDocs::SymbolTable->IndexChanged($index) || !exists $previousIndexes->{$index}) + { + $indexesToBuild{$index} = 1; + }; + }; + + # All indexes that still exist should have been deleted. + foreach my $index (keys %$previousIndexes) + { + if (!exists $currentIndexes->{$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->Builder()->BeginBuild( $numberOfFilesToBuild || $numberOfFilesToPurge || + $numberOfImagesToUpdate || $numberOfImagesToPurge || + $numberOfIndexesToBuild || $numberOfIndexesToPurge || + NaturalDocs::Menu->HasChanged() ); + }; + + if ($numberOfFilesToPurge) + { + NaturalDocs::StatusMessage->Start('Purging ' . $numberOfFilesToPurge + . ' file' . ($numberOfFilesToPurge > 1 ? 's' : '') . '...', + scalar @$buildTargets); + + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->PurgeFiles($filesToPurge); + NaturalDocs::StatusMessage->CompletedItem(); + }; + }; + + if ($numberOfIndexesToPurge) + { + NaturalDocs::StatusMessage->Start('Purging ' . $numberOfIndexesToPurge + . ' index' . ($numberOfIndexesToPurge > 1 ? 'es' : '') . '...', + scalar @$buildTargets); + + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->PurgeIndexes(\%indexesToPurge); + NaturalDocs::StatusMessage->CompletedItem(); + }; + }; + + if ($numberOfImagesToPurge) + { + NaturalDocs::StatusMessage->Start('Purging ' . $numberOfImagesToPurge + . ' image' . ($numberOfImagesToPurge > 1 ? 's' : '') . '...', + scalar @$buildTargets); + + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->PurgeImages($imagesToPurge); + NaturalDocs::StatusMessage->CompletedItem(); + }; + }; + + if ($numberOfFilesToBuild) + { + NaturalDocs::StatusMessage->Start('Building ' . $numberOfFilesToBuild + . ' file' . ($numberOfFilesToBuild > 1 ? 's' : '') . '...', + $numberOfFilesToBuild); + + foreach my $file (keys %$filesToBuild) + { + my $parsedFile = NaturalDocs::Parser->ParseForBuild($file); + + NaturalDocs::Error->OnStartBuilding($file); + + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->BuildFile($file, $parsedFile); + NaturalDocs::StatusMessage->CompletedItem(); + }; + + NaturalDocs::Error->OnEndBuilding($file); + }; + }; + + if ($numberOfIndexesToBuild) + { + NaturalDocs::StatusMessage->Start('Building ' . $numberOfIndexesToBuild + . ' index' . ($numberOfIndexesToBuild > 1 ? 'es' : '') . '...', + $numberOfIndexesToBuild); + + foreach my $index (keys %indexesToBuild) + { + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->BuildIndex($index); + NaturalDocs::StatusMessage->CompletedItem(); + }; + }; + }; + + if ($numberOfImagesToUpdate) + { + NaturalDocs::StatusMessage->Start('Updating ' . $numberOfImagesToUpdate + . ' image' . ($numberOfImagesToUpdate > 1 ? 's' : '') . '...', + $numberOfImagesToUpdate); + + foreach my $image (keys %$imagesToUpdate) + { + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->UpdateImage($image); + NaturalDocs::StatusMessage->CompletedItem(); + }; + }; + }; + + if (NaturalDocs::Menu->HasChanged()) + { + if (!NaturalDocs::Settings->IsQuiet()) + { print "Updating menu...\n"; }; + + foreach my $buildTarget (@$buildTargets) + { $buildTarget->Builder()->UpdateMenu(); }; + }; + + foreach my $buildTarget (@$buildTargets) + { + $buildTarget->Builder()->EndBuild($numberOfFilesToBuild || $numberOfFilesToPurge || + $numberOfIndexesToBuild || $numberOfIndexesToPurge || + $numberOfImagesToUpdate || $numberOfImagesToPurge || + NaturalDocs::Menu->HasChanged()); + }; + }; + + +1; diff --git a/docs/tool/Modules/NaturalDocs/Builder/Base.pm b/docs/tool/Modules/NaturalDocs/Builder/Base.pm new file mode 100644 index 00000000..0298264d --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/Builder/Base.pm @@ -0,0 +1,348 @@ +############################################################################### +# +# Class: NaturalDocs::Builder::Base +# +############################################################################### +# +# A base class for all Builder output formats. +# +############################################################################### + +# 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; + +package NaturalDocs::Builder::Base; + + +############################################################################### +# Group: Notes + + +# +# Topic: Implementation +# +# Builder packages are implemented as blessed arrayrefs, not hashrefs. This is done for all objects in Natural Docs for +# efficiency reasons. You create members by defining constants via and using them as +# indexes into the array. +# + +# +# Topic: Function Order +# +# The functions in the build process will always be called in the following order. +# +# - will always be called. +# - will be called next only if there's files that need to be purged. +# - will be called next only if there's indexes that need to be purged. +# - will e called next only if there's images that need to be purged. +# - will be called once for each file that needs to be built, if any. +# - will be called once for each index that changed and is part of the menu, if any. +# - will be called once for each image that needs to be updated, if any. +# - will be called next only if the menu changed. +# - will always be called. +# + +# +# Topic: How to Approach +# +# Here's an idea of how to approach making packages for different output types. +# +# +# Multiple Output Files, Embedded Menu: +# +# This example is for when you want to build one output file per source file, each with its own copy of the menu within it. +# This is how works. +# +# Make sure you create a function that generates just the menu for a particular source file. We'll need to generate menus for +# both building a file from scratch and for updating the menu on an existing output file, so it's better to give it its own function. +# You may want to surround it with something that can be easily detected in the output file to make replacing easier. +# +# isn't important. You don't need to implement it. +# +# Implement to delete the output files associated with the purged files. +# +# Implement to delete the output files associated with the purged indexes. +# +# Implement to create an output file for the parsed source file. Use the menu function described earlier. +# +# Implement to create an output file for each index. Use the menu function described earlier for each page. +# +# Implement to go through the list of unbuilt files and update their menus. You can get the list from +# UnbuiltFilesWithContent()>. You need to open their output files, replace the menu, and save it back +# to disk. Yes, it would be simpler from a programmer's point of view to just rebuild the file completely, but that would be +# _very_ inefficient since there could potentially be a _lot_ of files in this group. +# +# Also make sure goes through the unchanged indexes and updates them as well. +# +# isn't important. You don't need to implement it. +# +# +# Multiple Output Files, Menu in File: +# +# This example is for when you want to build one output file per source file, but keep the menu in its own separate file. This +# is how works. +# +# isn't important. You don't need to implement it. +# +# Implement to delete the output files associated with the purged files. +# +# Implement to delete the output files associated with the purged indexes. +# +# Implement to generate an output file from the parsed source file. +# +# Implement to generate an output file for each index. +# +# Implement to rebuild the menu file. +# +# isn't important. You don't need to implement it. +# +# +# Single Output File using Intermediate Files: +# +# This example is for when you want to build one output file, such as a PDF file, but use intermediate files to handle differential +# building. This would be much like how a compiler compiles each source file into a object file, and then a linker stitches them +# all together into the final executable file. +# +# isn't important. You don't need to implement it. +# +# Implement to delete the intermediate files associated with the purged files. +# +# Implement to delete the intermediate files associated with the purged indexes. +# +# Implement to generate an intermediate file from the parsed source file. +# +# Implement to generate an intermediate file for the specified index. +# +# Implement to generate the intermediate file for the menu. +# +# Implement so that if the project changed, it stitches the intermediate files together into the final +# output file. Make sure you check the parameter because the function will be called when nothing changes too. +# +# +# Single Output File using Direct Changes: +# +# This example is for when you want to build one output file, such as a PDF file, but engineering it in such a way that you don't +# need to use intermediate files. In other words, you're able to add, delete, and modify entries directly in the output file. +# +# Implement so that if the project changed, it opens the output file and does anything it needs to do +# to get ready for editing. +# +# Implement to remove the entries associated with the purged files. +# +# Implement to remove the entries associated with the purged indexes. +# +# Implement to add or replace a section of the output file with a new one generated from the parsed file. +# +# Implement to add or replace an index in the output file with a new one generated from the specified index. +# +# Implement so that if the project changed, it saves the output file to disk. +# +# How you handle the menu depends on how the output file references other sections of itself. If it can do so by name, then +# you can implement to update the menu section of the file and you're done. If it has to reference itself +# by address or offset, it gets trickier. You should skip and instead rebuild the menu in if +# the parameter is true. This lets you do it whenever anything changes in a file, rather than just when the menu +# visibly changes. How you keep track of the locations and how they change is your problem. +# + + +############################################################################### +# +# Group: Required Interface Functions +# +# All Builder classes *must* define these functions. +# + + +# +# Function: INIT +# +# Define this function to call Add()> so that knows about this package. +# Packages are defined this way so that new ones can be added without messing around in other code. +# + + +# +# Function: CommandLineOption +# +# Define this function to return the text that should be put in the command line after -o to use this package. It cannot have +# spaces and is not case sensitive. +# +# For example, returns 'html' so someone could use -o html [directory] to use that package. +# +sub CommandLineOption + { + NaturalDocs::Error->SoftDeath($_[0] . " didn't define CommandLineOption()."); + }; + + +# +# Function: BuildFile +# +# Define this function to convert a parsed file to this package's output format. This function will be called once for every source +# file that needs to be rebuilt. However, if a file hasn't changed since the last time Natural Docs was run, it will not be sent to +# this function. All packages must support differential build. +# +# Parameters: +# +# sourceFile - The name of the source file. +# parsedFile - The parsed source file, as an arrayref of objects. +# +sub BuildFile #(sourceFile, parsedFile) + { + NaturalDocs::Error->SoftDeath($_[0] . " didn't define BuildFile()."); + }; + + +############################################################################### +# +# Group: Optional Interface Functions +# +# These functions can be implemented but packages are not required to do so. +# + + +# +# Function: New +# +# Creates and returns a new object. +# +# Note that this is the only function where the first parameter will be the package name, not the object itself. +# +sub New + { + my $package = shift; + + my $object = [ ]; + bless $object, $package; + + return $object; + }; + + +# +# Function: BeginBuild +# +# Define this function if the package needs to do anything at the beginning of the build process. This function will be called +# every time Natural Docs is run, even if the project hasn't changed. This allows you to manage dependencies specific +# to the output format that may change independently from the source tree and menu. For example, +# needs to keep the CSS files in sync regardless of whether the source tree changed or not. +# +# Parameters: +# +# hasChanged - Whether the project has changed, such as source files or the menu file. If false, nothing else is going to be +# called except . +# +sub BeginBuild #(hasChanged) + { + }; + + +# +# Function: EndBuild +# +# Define this function if the package needs to do anything at the end of the build process. This function will be called every time +# Natural Docs is run, even if the project hasn't changed. This allows you to manage dependencies specific to the output +# format that may change independently from the source tree. For example, needs to keep the +# CSS files in sync regardless of whether the source tree changed or not. +# +# Parameters: +# +# hasChanged - Whether the project has changed, such as source files or the menu file. If false, the only other function that +# was called was . +# +sub EndBuild #(hasChanged) + { + }; + + +# +# Function: BuildIndex +# +# Define this function to create an index for the passed topic. You can get the index from +# Index()>. +# +# The reason it's not passed directly to this function is because indexes may be time-consuming to create. As such, they're +# generated on demand because some output packages may choose not to implement them. +# +# Parameters: +# +# topic - The to limit the index by. +# +sub BuildIndex #(topic) + { + }; + + +# +# Function: UpdateImage +# +# Define this function to add or update the passed image in the output. +# +# Parameters: +# +# file - The image +# +sub UpdateImage #(file) + { + }; + + +# +# Function: PurgeFiles +# +# Define this function to make the package remove all output related to the passed files. These files no longer have Natural Docs +# content. +# +# Parameters: +# +# files - An existence hashref of the files to purge. +# +sub PurgeFiles #(files) + { + }; + + +# +# Function: PurgeIndexes +# +# Define this function to make the package remove all output related to the passed indexes. These indexes are no longer part +# of the menu. +# +# Parameters: +# +# indexes - An existence hashref of the of the indexes to purge. +# +sub PurgeIndexes #(indexes) + { + }; + + +# +# Function: PurgeImages +# +# Define this function to make the package remove all output related to the passed image files. These files are no longer used +# by the documentation. +# +# Parameters: +# +# files - An existence hashref of the image to purge. +# +sub PurgeImages #(files) + { + }; + + +# +# Function: UpdateMenu +# +# Define this function to make the package update the menu. It will only be called if the menu changed. +# +sub UpdateMenu + { + }; + + +1; diff --git a/docs/tool/Modules/NaturalDocs/Builder/FramedHTML.pm b/docs/tool/Modules/NaturalDocs/Builder/FramedHTML.pm new file mode 100644 index 00000000..ab020aa6 --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/Builder/FramedHTML.pm @@ -0,0 +1,345 @@ +############################################################################### +# +# Package: NaturalDocs::Builder::FramedHTML +# +############################################################################### +# +# A package that generates output in HTML with frames. +# +# All functions are called with Package->Function() notation. +# +############################################################################### + +# 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; + +package NaturalDocs::Builder::FramedHTML; + +use base 'NaturalDocs::Builder::HTMLBase'; + + +############################################################################### +# Group: Implemented Interface Functions + + +# +# Function: INIT +# +# Registers the package with . +# +sub INIT + { + NaturalDocs::Builder->Add(__PACKAGE__); + }; + + +# +# Function: CommandLineOption +# +# Returns the option to follow -o to use this package. In this case, "html". +# +sub CommandLineOption + { + return 'FramedHTML'; + }; + + +# +# Function: BuildFile +# +# Builds the output file from the parsed source file. +# +# Parameters: +# +# sourcefile - The of the source file. +# parsedFile - An arrayref of the source file as objects. +# +sub BuildFile #(sourceFile, parsedFile) + { + my ($self, $sourceFile, $parsedFile) = @_; + + my $outputFile = $self->OutputFileOf($sourceFile); + + + # 99.99% of the time the output directory will already exist, so this will actually be more efficient. It only won't exist + # if a new file was added in a new subdirectory and this is the first time that file was ever parsed. + if (!open(OUTPUTFILEHANDLE, '>' . $outputFile)) + { + NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) ); + + open(OUTPUTFILEHANDLE, '>' . $outputFile) + or die "Couldn't create output file " . $outputFile . "\n"; + }; + + print OUTPUTFILEHANDLE + + + + # IE 6 doesn't like any doctype here at all. Add one (strict or transitional doesn't matter) and it makes the page slightly too + # wide for the frame. Mozilla and Opera handle it like champs either way because they Don't Suck(tm). + + # '' . "\n\n" + + '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $self->BuildTitle($sourceFile) + . '' + + . '' + + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . "\n\n\n" + . $self->BuildContent($sourceFile, $parsedFile) + . "\n\n\n" + + . $self->BuildToolTips() + + . $self->ClosingBrowserStyles() + . ''; + + + close(OUTPUTFILEHANDLE); + }; + + +# +# Function: BuildIndex +# +# Builds an index for the passed type. +# +# Parameters: +# +# type - The to limit the index to, or undef if none. +# +sub BuildIndex #(type) + { + my ($self, $type) = @_; + + my $indexTitle = $self->IndexTitleOf($type); + my $indexFile = $self->IndexFileOf($type); + + my $startIndexPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . ''; + + if (defined NaturalDocs::Menu->Title()) + { $startIndexPage .= $self->StringToHTML(NaturalDocs::Menu->Title()) . ' - '; }; + + $startIndexPage .= + $indexTitle + . '' + + . '' + + . '' + + . '' + . $self->OpeningBrowserStyles() + + . "\n\n\n" + . $self->StandardComments() + . "\n\n\n" + . '
' + . '
' + . $indexTitle + . '
'; + + + my $endIndexPage = + + '
' + . "\n\n\n" + + . $self->ClosingBrowserStyles() + + . ''; + + my $startSearchResultsPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + + . '' + . '' + + . '' + . $self->OpeningBrowserStyles() + + . "\n\n\n" + . $self->StandardComments() + . "\n\n\n" + + . '
' + . '
' + . 'Search Results' + . '
'; + + my $endSearchResultsPage = + + '
' + . "\n\n\n" + + . $self->ClosingBrowserStyles() + + . ''; + + my $indexContent = NaturalDocs::SymbolTable->Index($type); + my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage, + $startSearchResultsPage, $endSearchResultsPage); + $self->PurgeIndexFiles($type, $indexContent, $pageCount + 1); + }; + + +# +# Function: UpdateMenu +# +# Builds the menu file. Also generates index.html. +# +sub UpdateMenu + { + my $self = shift; + + my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self); + my $outputFile = NaturalDocs::File->JoinPaths($outputDirectory, 'menu.html'); + + + open(OUTPUTFILEHANDLE, '>' . $outputFile) + or die "Couldn't create output file " . $outputFile . "\n"; + + my $title = 'Menu'; + if (defined $title) + { $title .= ' - ' . NaturalDocs::Menu->Title(); }; + + $title = $self->StringToHTML($title); + + + print OUTPUTFILEHANDLE + + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $title + . '' + + . '' + + . '' + + . '' + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . "\n\n\n" + . $self->BuildMenu(undef, undef) + . "\n\n\n" + . $self->BuildFooter(1) + . "\n\n\n" + + . $self->ClosingBrowserStyles() + . ''; + + + close(OUTPUTFILEHANDLE); + + + # Update index.html + + my $firstMenuEntry = $self->FindFirstFile(); + my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' ); + + # We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu. + if (defined $firstMenuEntry) + { + open(INDEXFILEHANDLE, '>' . $indexFile) + or die "Couldn't create output file " . $indexFile . ".\n"; + + print INDEXFILEHANDLE + + '' + + . '' + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $self->StringToHTML(NaturalDocs::Menu->Title()) + . '' + + . '' + + . $self->StandardComments() + + . '' + . '' + . '' + . '' + + . '' + . 'This documentation was designed for use with frames. However, you can still use it by ' + . '<a href="menu.html">starting from the menu page</a>.' + . "<script language=JavaScript><!--\n" + . 'location.href="menu.html";' + . "\n// --></script>" + . '' + + . ''; + + close INDEXFILEHANDLE; + } + + elsif (-e $indexFile) + { + unlink($indexFile); + }; + }; + + +1; diff --git a/docs/tool/Modules/NaturalDocs/Builder/HTML.pm b/docs/tool/Modules/NaturalDocs/Builder/HTML.pm new file mode 100644 index 00000000..95f31b5a --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/Builder/HTML.pm @@ -0,0 +1,398 @@ +############################################################################### +# +# Package: NaturalDocs::Builder::HTML +# +############################################################################### +# +# A package that generates output in HTML. +# +# All functions are called with Package->Function() notation. +# +############################################################################### + +# 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; + +package NaturalDocs::Builder::HTML; + +use base 'NaturalDocs::Builder::HTMLBase'; + + +############################################################################### +# Group: Implemented Interface Functions + + +# +# Function: INIT +# +# Registers the package with . +# +sub INIT + { + NaturalDocs::Builder->Add(__PACKAGE__); + }; + + +# +# Function: CommandLineOption +# +# Returns the option to follow -o to use this package. In this case, "html". +# +sub CommandLineOption + { + return 'HTML'; + }; + + +# +# Function: BuildFile +# +# Builds the output file from the parsed source file. +# +# Parameters: +# +# sourcefile - The of the source file. +# parsedFile - An arrayref of the source file as objects. +# +sub BuildFile #(sourceFile, parsedFile) + { + my ($self, $sourceFile, $parsedFile) = @_; + + my $outputFile = $self->OutputFileOf($sourceFile); + + + # 99.99% of the time the output directory will already exist, so this will actually be more efficient. It only won't exist + # if a new file was added in a new subdirectory and this is the first time that file was ever parsed. + if (!open(OUTPUTFILEHANDLE, '>' . $outputFile)) + { + NaturalDocs::File->CreatePath( NaturalDocs::File->NoFileName($outputFile) ); + + open(OUTPUTFILEHANDLE, '>' . $outputFile) + or die "Couldn't create output file " . $outputFile . "\n"; + }; + + print OUTPUTFILEHANDLE + + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $self->BuildTitle($sourceFile) + . '' + + . '' + + . '' + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . "\n\n\n" + . $self->BuildContent($sourceFile, $parsedFile) + . "\n\n\n" + . $self->BuildFooter() + . "\n\n\n" + . $self->BuildMenu($sourceFile, undef) + . "\n\n\n" + . $self->BuildToolTips() + . "\n\n\n" + . '
' + . '' + . 'Close' + . '
' + . "\n\n\n" + + . $self->ClosingBrowserStyles() + . ''; + + + close(OUTPUTFILEHANDLE); + }; + + +# +# Function: BuildIndex +# +# Builds an index for the passed type. +# +# Parameters: +# +# type - The to limit the index to, or undef if none. +# +sub BuildIndex #(type) + { + my ($self, $type) = @_; + + my $indexTitle = $self->IndexTitleOf($type); + + my $startIndexPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $indexTitle; + + if (defined NaturalDocs::Menu->Title()) + { $startIndexPage .= ' - ' . $self->StringToHTML(NaturalDocs::Menu->Title()); }; + + $startIndexPage .= + '' + + . '' + + . '' + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . "\n\n\n" + + . '
' + . '
' + . $indexTitle + . '
'; + + my $endIndexPage = + '
' + + . "\n\n\n" + . $self->BuildFooter() + . "\n\n\n" + . $self->BuildMenu(undef, $type) + . "\n\n\n" + . '
' + . '' + . 'Close' + . '
' + . "\n\n\n" + + . $self->ClosingBrowserStyles() + . ''; + + + my $startSearchResultsPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . "\n\n\n" + + . '
'; + + + my $endSearchResultsPage = + '
' + . $self->ClosingBrowserStyles() + . ''; + + my $indexContent = NaturalDocs::SymbolTable->Index($type); + my $pageCount = $self->BuildIndexPages($type, $indexContent, $startIndexPage, $endIndexPage, + $startSearchResultsPage, $endSearchResultsPage); + $self->PurgeIndexFiles($type, $indexContent, $pageCount + 1); + }; + + +# +# Function: UpdateMenu +# +# Updates the menu in all the output files that weren't rebuilt. Also generates index.html. +# +sub UpdateMenu + { + my $self = shift; + + + # Update the menu on unbuilt files. + + my $filesToUpdate = NaturalDocs::Project->UnbuiltFilesWithContent(); + + foreach my $sourceFile (keys %$filesToUpdate) + { + $self->UpdateFile($sourceFile); + }; + + + # Update the menu on unchanged index files. + + my $indexes = NaturalDocs::Menu->Indexes(); + + foreach my $index (keys %$indexes) + { + if (!NaturalDocs::SymbolTable->IndexChanged($index)) + { + $self->UpdateIndex($index); + }; + }; + + + # Update index.html + + my $firstMenuEntry = $self->FindFirstFile(); + my $indexFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index.html' ); + + # We have to check because it's possible that there may be no files with Natural Docs content and thus no files on the menu. + if (defined $firstMenuEntry) + { + open(INDEXFILEHANDLE, '>' . $indexFile) + or die "Couldn't create output file " . $indexFile . ".\n"; + + print INDEXFILEHANDLE + '' + . '' + . ''; + + close INDEXFILEHANDLE; + } + + elsif (-e $indexFile) + { + unlink($indexFile); + }; + }; + + + +############################################################################### +# Group: Support Functions + + +# +# Function: UpdateFile +# +# Updates an output file. Replaces the menu, HTML title, and footer. It opens the output file, makes the changes, and saves it +# back to disk, which is much quicker than rebuilding the file from scratch if these were the only things that changed. +# +# Parameters: +# +# sourceFile - The source . +# +# Dependencies: +# +# - Requires to surround its content with the exact strings "". +# - Requires to surround its content with the exact strings "". +# +sub UpdateFile #(sourceFile) + { + my ($self, $sourceFile) = @_; + + my $outputFile = $self->OutputFileOf($sourceFile); + + if (open(OUTPUTFILEHANDLE, '<' . $outputFile)) + { + my $content; + + read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE); + close(OUTPUTFILEHANDLE); + + + $content =~ s{[^<]*<\/title>}{'<title>' . $self->BuildTitle($sourceFile) . ''}e; + + $content =~ s/