From 9ba8e6cf38da5196ed7bc878fe452952f3e10638 Mon Sep 17 00:00:00 2001 From: Magnus Auvinen Date: Tue, 22 May 2007 15:06:55 +0000 Subject: moved docs --- docs/doctool/Modules/NaturalDocs/Builder/Base.pm | 316 ++ .../Modules/NaturalDocs/Builder/FramedHTML.pm | 294 ++ docs/doctool/Modules/NaturalDocs/Builder/HTML.pm | 363 +++ .../Modules/NaturalDocs/Builder/HTMLBase.pm | 3075 ++++++++++++++++++++ 4 files changed, 4048 insertions(+) create mode 100644 docs/doctool/Modules/NaturalDocs/Builder/Base.pm create mode 100644 docs/doctool/Modules/NaturalDocs/Builder/FramedHTML.pm create mode 100644 docs/doctool/Modules/NaturalDocs/Builder/HTML.pm create mode 100644 docs/doctool/Modules/NaturalDocs/Builder/HTMLBase.pm (limited to 'docs/doctool/Modules/NaturalDocs/Builder') diff --git a/docs/doctool/Modules/NaturalDocs/Builder/Base.pm b/docs/doctool/Modules/NaturalDocs/Builder/Base.pm new file mode 100644 index 00000000..2d6cf468 --- /dev/null +++ b/docs/doctool/Modules/NaturalDocs/Builder/Base.pm @@ -0,0 +1,316 @@ +############################################################################### +# +# Class: NaturalDocs::Builder::Base +# +############################################################################### +# +# A base class for all Builder output formats. +# +############################################################################### + +# This file is part of Natural Docs, which is Copyright (C) 2003-2005 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 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 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: 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: 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/doctool/Modules/NaturalDocs/Builder/FramedHTML.pm b/docs/doctool/Modules/NaturalDocs/Builder/FramedHTML.pm new file mode 100644 index 00000000..7b615e4b --- /dev/null +++ b/docs/doctool/Modules/NaturalDocs/Builder/FramedHTML.pm @@ -0,0 +1,294 @@ +############################################################################### +# +# 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-2005 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() + + . $self->BuildContent($sourceFile, $parsedFile) + + . $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 $startPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . ''; + + if (defined NaturalDocs::Menu->Title()) + { $startPage .= $self->StringToHTML(NaturalDocs::Menu->Title()) . ' - '; }; + + $startPage .= + $indexTitle + . '' + + . '' + + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + . '
' + . $indexTitle + . '
'; + + + my $endPage = $self->ClosingBrowserStyles() . ''; + + + my $pageCount = $self->BuildIndexPages($type, NaturalDocs::SymbolTable->Index($type), $startPage, $endPage); + $self->PurgeIndexFiles($type, $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() + + . $self->BuildMenu(undef, undef, 1) + + . '' + + . $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/doctool/Modules/NaturalDocs/Builder/HTML.pm b/docs/doctool/Modules/NaturalDocs/Builder/HTML.pm new file mode 100644 index 00000000..92b4bd7f --- /dev/null +++ b/docs/doctool/Modules/NaturalDocs/Builder/HTML.pm @@ -0,0 +1,363 @@ +############################################################################### +# +# 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-2005 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() + + # I originally had this part done in CSS, but there were too many problems. Back to good old HTML tables. + . '' + + . '' . "\n\n" + + . '' . "\n\n" + + . '
' + + . $self->BuildContent($sourceFile, $parsedFile) + + . '
' + + . '' + + . $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 $startPage = + + '' . "\n\n" + + . '' + + . (NaturalDocs::Settings->CharSet() ? + '' : '') + + . '' + . $indexTitle; + + if (defined NaturalDocs::Menu->Title()) + { $startPage .= ' - ' . $self->StringToHTML(NaturalDocs::Menu->Title()); }; + + $startPage .= + '' + + . '' + + . '' + + . '' + . $self->OpeningBrowserStyles() + + . $self->StandardComments() + + # I originally had this part done in CSS, but there were too many problems. Back to good old HTML tables. + . '' + + . '' + + . '' + + . '
' + . '
' + . $indexTitle + . '
'; + + + my $endPage = + '
' + + . '' + + . $self->ClosingBrowserStyles() + . ''; + + + my $pageCount = $self->BuildIndexPages($type, NaturalDocs::SymbolTable->Index($type), $startPage, $endPage); + $self->PurgeIndexFiles($type, $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 . +# +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/.*?/$self->BuildMenu($sourceFile, undef, undef)/es; + + $content =~ s/.*?/$self->BuildFooter()/e; + + + open(OUTPUTFILEHANDLE, '>' . $outputFile); + print OUTPUTFILEHANDLE $content; + close(OUTPUTFILEHANDLE); + }; + }; + + +# +# Function: UpdateIndex +# +# Updates an index's output file. Replaces the menu 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: +# +# type - The index , or undef if none. +# +sub UpdateIndex #(type) + { + my ($self, $type) = @_; + + my $page = 1; + + my $outputFile = $self->IndexFileOf($type, $page); + + my $newMenu = $self->BuildMenu(undef, $type, undef); + my $newFooter = $self->BuildFooter(); + + while (-e $outputFile) + { + open(OUTPUTFILEHANDLE, '<' . $outputFile) + or die "Couldn't open output file " . $outputFile . ".\n"; + + my $content; + + read(OUTPUTFILEHANDLE, $content, -s OUTPUTFILEHANDLE); + close(OUTPUTFILEHANDLE); + + + $content =~ s/.*?/$newMenu/es; + + $content =~ s/