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 --- .../Modules/NaturalDocs/ImageReferenceTable.pm | 383 +++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm (limited to 'docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm') diff --git a/docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm b/docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm new file mode 100644 index 00000000..8f13ce5f --- /dev/null +++ b/docs/tool/Modules/NaturalDocs/ImageReferenceTable.pm @@ -0,0 +1,383 @@ +############################################################################### +# +# Package: NaturalDocs::ImageReferenceTable +# +############################################################################### +# +# A -based package that manages all the image references appearing in source files. +# +############################################################################### + +# 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::ImageReferenceTable::String; +use NaturalDocs::ImageReferenceTable::Reference; + + +package NaturalDocs::ImageReferenceTable; + +use base 'NaturalDocs::SourceDB::Extension'; + + +############################################################################### +# Group: Information + +# +# Topic: Usage +# +# - and must be initialized before this package can be used. +# +# - Call before using. +# +# +# Topic: Programming Notes +# +# When working on this code, remember that there are three things it has to juggle. +# +# - The information in . +# - Image file references in . +# - Source file rebuilding on changes. +# +# Managing the actual image files will be handled between and the +# sub-packages. +# +# +# Topic: Implementation +# +# Managing image references is simpler than managing the references in . In SymbolTable, +# you have to worry about reference targets popping into and out of existence. A link may go to a file that hasn't been +# reparsed yet and the target may no longer exist. We have to deal with that when we know it, which may be after the +# reference's file was parsed. Also, a new definition may appear that serves as a better interpretation of a link than its +# current target, and again we may only know that after the reference's file has been parsed already. So we have to deal +# with scores and potential symbols and each symbol knowing exactly what links to it and so forth. +# +# Not so with image references. All possible targets (all possible image files) are known by early +# on and will remain consistent throughout execution. So because of that, we can get away with only storing reference +# counts with each image and determining exactly where a reference points to as we find them. +# +# Reference counts are stored with the image file information in . However, it is not loaded and +# saved to disk by it. Rather, it is regenerated by this package when it loads . +# NaturalDocs::Project only stores the last modification time (so it can add files to the build list if they've changed) and +# whether it had any references at all on the last run (so it knows whether it should care if they've changed.) +# ImageReferenceTable.nd stores each reference's target, width, and height. Whether their interpretations have changed is +# dealt with in the function, again since the list of targets (image files) is constant. +# +# The package is based on , so read it's documentation for more information on how it works. +# + + +############################################################################### +# Group: Variables + + +# +# var: extensionID +# The granted by . +# +my $extensionID; + + + +############################################################################### +# Group: Files + + +# +# File: ImageReferenceTable.nd +# +# The data file which stores all the image references from the last run of Natural Docs. +# +# Format: +# +# > [Standard Binary Header] +# +# It starts with the standard binary header from . +# +# > [Image Reference String or undef] +# > [AString16: target file] +# > [UInt16: target width or 0] +# > [UInt16: target height or 0] +# +# For each , it's target, width, and height are stored. The target is needed so we can tell if it +# changed from the last run, and the dimensions are needed because if the target hasn't changed but the file's dimensions +# have, the source files need to be rebuilt. +# +# are encoded by . +# +# > [AString16: definition file or undef] ... +# +# Then comes a series of AString16s for all the files that define the reference until it hits an undef. +# +# This whole series is repeated for each until it hits an undef. +# +# Revisions: +# +# 1.4: +# +# - The file was added to Natural Docs. +# + + + +############################################################################### +# Group: Functions + + +# +# Function: Register +# Registers the package with . +# +sub Register + { + my $self = shift; + $extensionID = NaturalDocs::SourceDB->RegisterExtension($self, 0); + }; + + +# +# Function: Load +# +# Loads the data from . Returns whether it was successful. +# +sub Load # => bool + { + my $self = shift; + + if (NaturalDocs::Settings->RebuildData()) + { return 0; }; + + # The file format hasn't changed since it was introduced. + if (!NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') )) + { return 0; }; + + + # [Image Reference String or undef] + while (my $referenceString = NaturalDocs::ImageReferenceTable::String->FromBinaryFile()) + { + NaturalDocs::SourceDB->AddItem($extensionID, $referenceString, + NaturalDocs::ImageReferenceTable::Reference->New()); + + # [AString16: target file] + # [UInt16: target width or 0] + # [UInt16: target height or 0] + + my $targetFile = NaturalDocs::BinaryFile->GetAString16(); + my $width = NaturalDocs::BinaryFile->GetUInt16(); + my $height = NaturalDocs::BinaryFile->GetUInt16(); + + my $newTargetFile = $self->SetReferenceTarget($referenceString); + my $newWidth; + my $newHeight; + + if ($newTargetFile) + { + NaturalDocs::Project->AddImageFileReference($newTargetFile); + ($newWidth, $newHeight) = NaturalDocs::Project->ImageFileDimensions($newTargetFile); + }; + + my $rebuildDefinitions = ($newTargetFile ne $targetFile || $newWidth != $width || $newHeight != $height); + + + # [AString16: definition file or undef] ... + while (my $definitionFile = NaturalDocs::BinaryFile->GetAString16()) + { + NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $definitionFile); + + if ($rebuildDefinitions) + { NaturalDocs::Project->RebuildFile($definitionFile); }; + }; + }; + + + NaturalDocs::BinaryFile->Close(); + return 1; + }; + + +# +# Function: Save +# +# Saves the data to . +# +sub Save + { + my $self = shift; + + my $references = NaturalDocs::SourceDB->GetAllItemsHashRef($extensionID); + + NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('ImageReferenceTable.nd') ); + + while (my ($referenceString, $referenceObject) = each %$references) + { + # [Image Reference String or undef] + # [AString16: target file] + # [UInt16: target width or 0] + # [UInt16: target height or 0] + + NaturalDocs::ImageReferenceTable::String->ToBinaryFile($referenceString); + + my $target = $referenceObject->Target(); + my ($width, $height); + + if ($target) + { ($width, $height) = NaturalDocs::Project->ImageFileDimensions($target); }; + + NaturalDocs::BinaryFile->WriteAString16( $referenceObject->Target() ); + NaturalDocs::BinaryFile->WriteUInt16( ($width || 0) ); + NaturalDocs::BinaryFile->WriteUInt16( ($height || 0) ); + + # [AString16: definition file or undef] ... + + my $definitions = $referenceObject->GetAllDefinitionsHashRef(); + + foreach my $definition (keys %$definitions) + { NaturalDocs::BinaryFile->WriteAString16($definition); }; + + NaturalDocs::BinaryFile->WriteAString16(undef); + }; + + NaturalDocs::ImageReferenceTable::String->ToBinaryFile(undef); + + NaturalDocs::BinaryFile->Close(); + }; + + +# +# Function: AddReference +# +# Adds a new image reference. +# +sub AddReference #(FileName file, string referenceText) + { + my ($self, $file, $referenceText) = @_; + + my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($file, $referenceText); + + if (!NaturalDocs::SourceDB->HasItem($extensionID, $referenceString)) + { + my $referenceObject = NaturalDocs::ImageReferenceTable::Reference->New(); + NaturalDocs::SourceDB->AddItem($extensionID, $referenceString, $referenceObject); + + my $target = $self->SetReferenceTarget($referenceString); + if ($target) + { NaturalDocs::Project->AddImageFileReference($target); }; + }; + + NaturalDocs::SourceDB->AddDefinition($extensionID, $referenceString, $file); + }; + + +# +# Function: OnDeletedDefinition +# +# Called for each definition deleted by . This is called *after* the definition has been deleted from +# the database, so don't expect to be able to read it. +# +sub OnDeletedDefinition #(ImageReferenceString referenceString, FileName file, bool wasLastDefinition) + { + my ($self, $referenceString, $file, $wasLastDefinition) = @_; + + if ($wasLastDefinition) + { + my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString); + my $target = $referenceObject->Target(); + + if ($target) + { NaturalDocs::Project->DeleteImageFileReference($target); }; + + NaturalDocs::SourceDB->DeleteItem($extensionID, $referenceString); + }; + }; + + +# +# Function: GetReferenceTarget +# +# Returns the image file the reference resolves to, or undef if none. +# +# Parameters: +# +# sourceFile - The source the reference appears in. +# text - The reference text. +# +sub GetReferenceTarget #(FileName sourceFile, string text) => FileName + { + my ($self, $sourceFile, $text) = @_; + + my $referenceString = NaturalDocs::ImageReferenceTable::String->Make($sourceFile, $text); + my $reference = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString); + + if (!defined $reference) + { return undef; } + else + { return $reference->Target(); }; + }; + + +# +# Function: SetReferenceTarget +# +# Determines the best target for the passed and sets it on the +# object. Returns the new target . Does *not* add any source +# files to the bulid list. +# +sub SetReferenceTarget #(ImageReferenceString referenceString) => FileName + { + my ($self, $referenceString) = @_; + + my $referenceObject = NaturalDocs::SourceDB->GetItem($extensionID, $referenceString); + my ($sourcePath, $text) = NaturalDocs::ImageReferenceTable::String->InformationOf($referenceString); + + + # Try the path relative to the source file first. + + my $target; + + my $imageFile = NaturalDocs::File->JoinPaths($sourcePath, $text); + my $exists = NaturalDocs::Project->ImageFileExists($imageFile); + + + # Then try relative image directories. + + if (!$exists) + { + my $relativeImageDirectories = NaturalDocs::Settings->RelativeImageDirectories(); + + for (my $i = 0; $i < scalar @$relativeImageDirectories && !$exists; $i++) + { + $imageFile = NaturalDocs::File->JoinPaths($sourcePath, $relativeImageDirectories->[$i], 1); + $imageFile = NaturalDocs::File->JoinPaths($imageFile, $text); + + $exists = NaturalDocs::Project->ImageFileExists($imageFile); + }; + }; + + + # Then try absolute image directories. + + if (!$exists) + { + my $imageDirectories = NaturalDocs::Settings->ImageDirectories(); + + for (my $i = 0; $i < scalar @$imageDirectories && !$exists; $i++) + { + $imageFile = NaturalDocs::File->JoinPaths($imageDirectories->[$i], $text); + $exists = NaturalDocs::Project->ImageFileExists($imageFile); + }; + }; + + + if ($exists) + { $target = NaturalDocs::Project->ImageFileCapitalization($imageFile); }; + #else leave it as undef. + + $referenceObject->SetTarget($target); + return $target; + }; + + +1; -- cgit 1.4.1