about summary refs log tree commit diff
path: root/docs/doctool/Modules/NaturalDocs/Languages.pm
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-01-17 12:56:19 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-01-17 12:56:19 +0000
commite42c493d0c294ccb0a314c8447818c8d613195df (patch)
tree27e56d9415313ddccdb1550da64ed3ef80b1dcca /docs/doctool/Modules/NaturalDocs/Languages.pm
parent037569c4e52f37196275dbafec670f54da249cf8 (diff)
downloadzcatch-e42c493d0c294ccb0a314c8447818c8d613195df.tar.gz
zcatch-e42c493d0c294ccb0a314c8447818c8d613195df.zip
removed olds docs
Diffstat (limited to 'docs/doctool/Modules/NaturalDocs/Languages.pm')
-rw-r--r--docs/doctool/Modules/NaturalDocs/Languages.pm1471
1 files changed, 0 insertions, 1471 deletions
diff --git a/docs/doctool/Modules/NaturalDocs/Languages.pm b/docs/doctool/Modules/NaturalDocs/Languages.pm
deleted file mode 100644
index 4f29634c..00000000
--- a/docs/doctool/Modules/NaturalDocs/Languages.pm
+++ /dev/null
@@ -1,1471 +0,0 @@
-###############################################################################
-#
-#   Package: NaturalDocs::Languages
-#
-###############################################################################
-#
-#   A package to manage all the programming languages Natural Docs supports.
-#
-#   Usage and Dependencies:
-#
-#       - Prior to use, <NaturalDocs::Settings> must be initialized and <Load()> must be called.
-#
-###############################################################################
-
-# This file is part of Natural Docs, which is Copyright (C) 2003-2005 Greg Valure
-# Natural Docs is licensed under the GPL
-
-use Text::Wrap();
-
-use NaturalDocs::Languages::Prototype;
-
-use NaturalDocs::Languages::Base;
-use NaturalDocs::Languages::Simple;
-use NaturalDocs::Languages::Advanced;
-
-use NaturalDocs::Languages::Perl;
-use NaturalDocs::Languages::CSharp;
-use NaturalDocs::Languages::ActionScript;
-
-use NaturalDocs::Languages::Ada;
-use NaturalDocs::Languages::PLSQL;
-use NaturalDocs::Languages::Pascal;
-use NaturalDocs::Languages::Tcl;
-
-use strict;
-use integer;
-
-package NaturalDocs::Languages;
-
-
-###############################################################################
-# Group: Variables
-
-
-#
-#   handle: FH_LANGUAGES
-#
-#   The file handle used for writing to <Languages.txt>.
-#
-
-
-#
-#   hash: languages
-#
-#   A hash of all the defined languages.  The keys are the all-lowercase language names, and the values are
-#   <NaturalDocs::Languages::Base>-derived objects.
-#
-my %languages;
-
-#
-#   hash: extensions
-#
-#   A hash of all the defined languages' extensions.  The keys are the all-lowercase extensions, and the values are the
-#   all-lowercase names of the languages that defined them.
-#
-my %extensions;
-
-#
-#   hash: shebangStrings
-#
-#   A hash of all the defined languages' strings to search for in the shebang (#!) line.  The keys are the all-lowercase strings, and
-#   the values are the all-lowercase names of the languages that defined them.
-#
-my %shebangStrings;
-
-#
-#   hash: shebangFiles
-#
-#   A hash of all the defined languages for files where it needs to be found via shebang strings.  The keys are the file names,
-#   and the values are language names, or undef if the file isn't supported.  These values should be filled in the first time
-#   each file is parsed for a shebang string so that it doesn't have to be done multiple times.
-#
-my %shebangFiles;
-
-#
-#   array: mainLanguageNames
-#
-#   An array of the language names that are defined in the main <Languages.txt>.
-#
-my @mainLanguageNames;
-
-
-
-###############################################################################
-# Group: Files
-
-
-#
-#   File: Languages.txt
-#
-#   The configuration file that defines or overrides the language definitions for Natural Docs.  One version sits in Natural Docs'
-#   configuration directory, and another can be in a project directory to add to or override them.
-#
-#   > # [comments]
-#
-#   Everything after a # symbol is ignored.  However, for this particular file, comments can only appear on their own lines.
-#   They cannot appear after content on the same line.
-#
-#   > Format: [version]
-#
-#   Specifies the file format version of the file.
-#
-#
-#   Sections:
-#
-#       > Ignore[d] Extension[s]: [extension] [extension] ...
-#
-#       Causes the listed file extensions to be ignored, even if they were previously defined to be part of a language.  The list is
-#       space-separated.  ex. "Ignore Extensions: cvs txt"
-#
-#
-#       > Language: [name]
-#
-#       Creates a new language.  Everything underneath applies to this language until the next one.  Names can use any
-#       characters.
-#
-#       The languages "Text File" and "Shebang Script" have special meanings.  Text files are considered all comment and don't
-#       have comment symbols.  Shebang scripts have their language determined by the shebang string and automatically
-#       include files with no extension in addition to the extensions defined.
-#
-#       If "Text File" doesn't define ignored prefixes, a package separator, or enum value behavior, those settings will be copied
-#       from the language with the most files in the source tree.
-#
-#
-#       > Alter Language: [name]
-#
-#       Alters an existing language.  Everything underneath it overrides the previous settings until the next one.  Note that if a
-#       property has an [Add/Replace] form and that property has already been defined, you have to specify whether you're adding
-#       to or replacing the defined list.
-#
-#
-#   Language Properties:
-#
-#       > Extension[s]: [extension] [extension] ...
-#       > [Add/Replace] Extension[s]: ...
-#
-#       Defines file extensions for the language's source files.  The list is space-separated.  ex. "Extensions: c cpp".  You can use
-#       extensions that were previously used by another language to redefine them.
-#
-#
-#       > Shebang String[s]: [string] [string] ...
-#       > [Add/Replace] Shebang String[s]: ...
-#
-#       Defines a list of strings that can appear in the shebang (#!) line to designate that it's part of this language.  They can
-#       appear anywhere in the line, so "php" will work for "#!/user/bin/php4".  You can use strings that were previously used by
-#       another language to redefine them.
-#
-#
-#       > Ignore[d] Prefix[es] in Index: [prefix] [prefix] ...
-#       > Ignore[d] [Topic Type] Prefix[es] in Index: [prefix] [prefix] ...
-#       > [Add/Replace] Ignore[d] Prefix[es] in Index: ...
-#       > [Add/Replace] Ignore[d] [Topic Type] Prefix[es] in Index: ...
-#
-#       Specifies prefixes that should be ignored when sorting symbols for an index.  Can be specified in general or for a specific
-#       <TopicType>.  The prefixes will still appear, the symbols will just be sorted as if they're not there.  For example, specifying
-#       "ADO_" for functions will mean that "ADO_DoSomething" will appear under D instead of A.
-#
-#
-#   Basic Language Support Properties:
-#
-#       These attributes are only available for languages with basic language support.
-#
-#
-#       > Line Comment[s]: [symbol] [symbol] ...
-#
-#       Defines a space-separated list of symbols that are used for line comments, if any.  ex. "Line Comment: //".
-#
-#
-#       > Block Comment[s]: [opening symbol] [closing symbol] [opening symbol] [closing symbol] ...
-#
-#       Defines a space-separated list of symbol pairs that are used for block comments, if any.  ex. "Block Comment: /* */".
-#
-#
-#       > Package Separator: [symbol]
-#
-#       Defines the default package separator symbol, such as . or ::.  This is for presentation only and will not affect how
-#       Natural Docs links are parsed.  The default is a dot.
-#
-#
-#       > [Topic Type] Prototype Ender[s]: [symbol] [symbol] ...
-#
-#       When defined, Natural Docs will attempt to collect prototypes from the code following the specified <TopicType>.  It grabs
-#       code until the first ender symbol or the next Natural Docs comment, and if it contains the topic name, it serves as its
-#       prototype.  Use \n to specify a line break.  ex. "Function Prototype Enders: { ;", "Variable Prototype Enders: = ;".
-#
-#
-#       > Line Extender: [symbol]
-#
-#       Defines the symbol that allows a prototype to span multiple lines if normally a line break would end it.
-#
-#
-#       > Enum Values: [global|under type|under parent]
-#
-#       Defines how enum values are referenced.  The default is global.
-#
-#       global - Values are always global, referenced as 'value'.
-#       under type - Values are under the enum type, referenced as 'package.enum.value'.
-#       under parent - Values are under the enum's parent, referenced as 'package.value'.
-#
-#
-#       > Perl Package: [perl package]
-#
-#       Specifies the Perl package used to fine-tune the language behavior in ways too complex to do in this file.
-#
-#
-#   Full Language Support Properties:
-#
-#       These attributes are only available for languages with full language support.
-#
-#
-#       > Full Language Support: [perl package]
-#
-#       Specifies the Perl package that has the parsing routines necessary for full language support.
-#
-#
-#   Revisions:
-#
-#       1.32:
-#
-#           - Package Separator is now a basic language support only property.
-#           - Added Enum Values setting.
-#
-#       1.3:
-#
-#           - The file was introduced.
-
-
-###############################################################################
-# Group: File Functions
-
-
-#
-#   Function: Load
-#
-#   Loads both the master and the project version of <Languages.txt>.
-#
-sub Load
-    {
-    my $self = shift;
-
-    # Hashrefs where the keys are all-lowercase extensions/shebang strings, and the values are arrayrefs of the languages
-    # that defined them, earliest first, all lowercase.
-    my %tempExtensions;
-    my %tempShebangStrings;
-
-    $self->LoadFile(1, \%tempExtensions, \%tempShebangStrings);  # Main
-
-    if (!exists $languages{'shebang script'})
-        {  NaturalDocs::ConfigFile->AddError('You must define "Shebang Script" in the main languages file.');  };
-    if (!exists $languages{'text file'})
-        {  NaturalDocs::ConfigFile->AddError('You must define "Text File" in the main languages file.');  };
-
-    my $errorCount = NaturalDocs::ConfigFile->ErrorCount();
-
-    if ($errorCount)
-        {
-        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
-        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
-                                                    . ' in ' . NaturalDocs::Project->MainLanguagesFile());
-        }
-
-
-    $self->LoadFile(0, \%tempExtensions, \%tempShebangStrings);  # User
-
-    $errorCount = NaturalDocs::ConfigFile->ErrorCount();
-
-    if ($errorCount)
-        {
-        NaturalDocs::ConfigFile->PrintErrorsAndAnnotateFile();
-        NaturalDocs::Error->SoftDeath('There ' . ($errorCount == 1 ? 'is an error' : 'are ' . $errorCount . ' errors')
-                                                    . ' in ' . NaturalDocs::Project->UserLanguagesFile());
-        };
-
-
-    # Convert the temp hashes into the real ones.
-
-    while (my ($extension, $languages) = each %tempExtensions)
-        {
-        $extensions{$extension} = $languages->[-1];
-        };
-    while (my ($shebangString, $languages) = each %tempShebangStrings)
-        {
-        $shebangStrings{$shebangString} = $languages->[-1];
-        };
-    };
-
-
-#
-#   Function: LoadFile
-#
-#   Loads a particular version of <Languages.txt>.
-#
-#   Parameters:
-#
-#       isMain - Whether the file is the main file or not.
-#       tempExtensions - A hashref where the keys are all-lowercase extensions, and the values are arrayrefs of the all-lowercase
-#                                 names of the languages that defined them, earliest first.  It will be changed by this function.
-#       tempShebangStrings - A hashref where the keys are all-lowercase shebang strings, and the values are arrayrefs of the
-#                                        all-lowercase names of the languages that defined them, earliest first.  It will be changed by this
-#                                        function.
-#
-sub LoadFile #(isMain, tempExtensions, tempShebangStrings)
-    {
-    my ($self, $isMain, $tempExtensions, $tempShebangStrings) = @_;
-
-    my ($file, $status);
-
-    if ($isMain)
-        {
-        $file = NaturalDocs::Project->MainLanguagesFile();
-        $status = NaturalDocs::Project->MainLanguagesFileStatus();
-        }
-    else
-        {
-        $file = NaturalDocs::Project->UserLanguagesFile();
-        $status = NaturalDocs::Project->UserLanguagesFileStatus();
-        };
-
-
-    my $version;
-
-    # An array of properties for the current language.  Each entry is the three consecutive values ( lineNumber, keyword, value ).
-    my @properties;
-
-    if ($version = NaturalDocs::ConfigFile->Open($file))
-        {
-        # The format hasn't changed significantly since the file was introduced.
-
-        if ($status == ::FILE_CHANGED())
-            {
-            NaturalDocs::Project->ReparseEverything();
-            NaturalDocs::SymbolTable->RebuildAllIndexes();  # Because the ignored prefixes could change.
-            };
-
-        my ($keyword, $value, $comment);
-
-        while (($keyword, $value, $comment) = NaturalDocs::ConfigFile->GetLine())
-            {
-            $value .= $comment;
-            $value =~ s/^ //;
-
-            # Process previous properties.
-            if (($keyword eq 'language' || $keyword eq 'alter language') && scalar @properties)
-                {
-                if ($isMain && $properties[1] eq 'language')
-                    {  push @mainLanguageNames, $properties[2];  };
-
-                $self->ProcessProperties(\@properties, $version, $tempExtensions, $tempShebangStrings);
-                @properties = ( );
-                };
-
-            if ($keyword =~ /^ignored? extensions?$/)
-                {
-                $value =~ tr/.*//d;
-                my @extensions = split(/ /, lc($value));
-
-                foreach my $extension (@extensions)
-                    {  delete $tempExtensions->{$extension};  };
-                }
-            else
-                {
-                push @properties, NaturalDocs::ConfigFile->LineNumber(), $keyword, $value;
-                };
-            };
-
-        if (scalar @properties)
-            {
-            if ($isMain && $properties[1] eq 'language')
-                {  push @mainLanguageNames, $properties[2];  };
-
-            $self->ProcessProperties(\@properties, $version, $tempExtensions, $tempShebangStrings);
-            };
-        }
-
-    else # couldn't open file
-        {
-        if ($isMain)
-            {  die "Couldn't open languages file " . $file . "\n";  };
-        };
-    };
-
-
-#
-#   Function: ProcessProperties
-#
-#   Processes an array of language properties from <Languages.txt>.
-#
-#   Parameters:
-#
-#       properties - An arrayref of properties where each entry is the three consecutive values ( lineNumber, keyword, value ).
-#                         It must start with the Language or Alter Language property.
-#       version - The <VersionInt> of the file.
-#       tempExtensions - A hashref where the keys are all-lowercase extensions, and the values are arrayrefs of the all-lowercase
-#                                 names of the languages that defined them, earliest first.  It will be changed by this function.
-#       tempShebangStrings - A hashref where the keys are all-lowercase shebang strings, and the values are arrayrefs of the
-#                                        all-lowercase names of the languages that defined them, earliest first.  It will be changed by this
-#                                        function.
-#
-sub ProcessProperties #(properties, version, tempExtensions, tempShebangStrings)
-    {
-    my ($self, $properties, $version, $tempExtensions, $tempShebangStrings) = @_;
-
-
-    # First validate the name and check whether the language has full support.
-
-    my $language;
-    my $fullLanguageSupport;
-    my ($lineNumber, $languageKeyword, $languageName) = @$properties[0..2];
-    my $lcLanguageName = lc($languageName);
-    my ($keyword, $value);
-
-    if ($languageKeyword eq 'alter language')
-        {
-        $language = $languages{$lcLanguageName};
-
-        if (!defined $language)
-            {
-            NaturalDocs::ConfigFile->AddError('The language ' . $languageName . ' is not defined.', $lineNumber);
-            return;
-            }
-        else
-            {
-            $fullLanguageSupport = (!$language->isa('NaturalDocs::Languages::Simple'));
-            };
-        }
-
-    elsif ($languageKeyword eq 'language')
-        {
-        if (exists $languages{$lcLanguageName})
-            {
-            NaturalDocs::ConfigFile->AddError('The language ' . $value . ' is already defined.  Use "Alter Language" if you want '
-                                                             . 'to override its settings.', $lineNumber);
-            return;
-            };
-
-        # Case is important with these two.
-        if ($lcLanguageName eq 'shebang script')
-            {  $languageName = 'Shebang Script';  }
-        elsif ($lcLanguageName eq 'text file')
-            {  $languageName = 'Text File';  };
-
-
-        # Go through the properties looking for whether the language has basic or full support and which package to use to create
-        # it.
-
-        for (my $i = 3; $i < scalar @$properties; $i += 3)
-            {
-            ($lineNumber, $keyword, $value) = @$properties[$i..$i+2];
-
-            if ($keyword eq 'full language support')
-                {
-                $fullLanguageSupport = 1;
-
-                eval
-                    {
-                    $language = $value->New($languageName);
-                    };
-                if ($::EVAL_ERROR)
-                    {
-                    NaturalDocs::ConfigFile->AddError('Could not create ' . $value . ' object.', $lineNumber);
-                    return;
-                    };
-
-                last;
-                }
-
-            elsif ($keyword eq 'perl package')
-                {
-                eval
-                    {
-                    $language = $value->New($languageName);
-                    };
-                if ($::EVAL_ERROR)
-                    {
-                    NaturalDocs::ConfigFile->AddError('Could not create ' . $value . ' object.', $lineNumber);
-                    return;
-                    };
-                };
-            };
-
-        # If $language was not created by now, it's a generic basic support language.
-        if (!defined $language)
-            {  $language = NaturalDocs::Languages::Simple->New($languageName);  };
-
-        $languages{$lcLanguageName} = $language;
-        }
-
-    else # not language or alter language
-        {
-        NaturalDocs::ConfigFile->AddError('You must start this line with "Language", "Alter Language", or "Ignore Extensions".',
-                                                           $lineNumber);
-        return;
-        };
-
-
-    # Decode the properties.
-
-    for (my $i = 3; $i < scalar @$properties; $i += 3)
-        {
-        ($lineNumber, $keyword, $value) = @$properties[$i..$i+2];
-
-        if ($keyword =~ /^(?:(add|replace) )?extensions?$/)
-            {
-            my $command = $1;
-
-
-            # Remove old extensions.
-
-            if (defined $language->Extensions() && $command eq 'replace')
-                {
-                foreach my $extension (@{$language->Extensions()})
-                    {
-                    if (exists $tempExtensions->{$extension})
-                        {
-                        my $languages = $tempExtensions->{$extension};
-                        my $i = 0;
-
-                        while ($i < scalar @$languages)
-                            {
-                            if ($languages->[$i] eq $lcLanguageName)
-                                {  splice(@$languages, $i, 1);  }
-                            else
-                                {  $i++;  };
-                            };
-
-                        if (!scalar @$languages)
-                            {  delete $tempExtensions->{$extension};  };
-                        };
-                    };
-                };
-
-
-            # Add new extensions.
-
-            # Ignore stars and dots so people could use .ext or *.ext.
-            $value =~ s/\*\.|\.//g;
-
-            my @extensions = split(/ /, lc($value));
-
-            foreach my $extension (@extensions)
-                {
-                if (!exists $tempExtensions->{$extension})
-                    {  $tempExtensions->{$extension} = [ ];  };
-
-                push @{$tempExtensions->{$extension}}, $lcLanguageName;
-                };
-
-
-            # Set the extensions for the language object.
-
-            if (defined $language->Extensions())
-                {
-                if ($command eq 'add')
-                    {  push @extensions, @{$language->Extensions()};  }
-                elsif (!$command)
-                    {
-                    NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of extensions.',
-                                                                       $lineNumber);
-                    };
-                };
-
-            $language->SetExtensions(\@extensions);
-            }
-
-        elsif ($keyword =~ /^(?:(add|replace) )?shebang strings?$/)
-            {
-            my $command = $1;
-
-
-            # Remove old strings.
-
-            if (defined $language->ShebangStrings() && $command eq 'replace')
-                {
-                foreach my $shebangString (@{$language->ShebangStrings()})
-                    {
-                    if (exists $tempShebangStrings->{$shebangString})
-                        {
-                        my $languages = $tempShebangStrings->{$shebangString};
-                        my $i = 0;
-
-                        while ($i < scalar @$languages)
-                            {
-                            if ($languages->[$i] eq $lcLanguageName)
-                                {  splice(@$languages, $i, 1);  }
-                            else
-                                {  $i++;  };
-                            };
-
-                        if (!scalar @$languages)
-                            {  delete $tempShebangStrings->{$shebangString};  };
-                        };
-                    };
-                };
-
-
-            # Add new strings.
-
-            my @shebangStrings = split(/ /, lc($value));
-
-            foreach my $shebangString (@shebangStrings)
-                {
-                if (!exists $tempShebangStrings->{$shebangString})
-                    {  $tempShebangStrings->{$shebangString} = [ ];  };
-
-                push @{$tempShebangStrings->{$shebangString}}, $lcLanguageName;
-                };
-
-
-            # Set the strings for the language object.
-
-            if (defined $language->ShebangStrings())
-                {
-                if ($command eq 'add')
-                    {  push @shebangStrings, @{$language->ShebangStrings()};  }
-                elsif (!$command)
-                    {
-                    NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of shebang '
-                                                                     . 'strings.', $lineNumber);
-                    };
-                };
-
-            $language->SetShebangStrings(\@shebangStrings);
-            }
-
-        elsif ($keyword eq 'package separator')
-            {
-            if ($fullLanguageSupport)
-                {
-                # Prior to 1.32, package separator was used with full language support too.  Accept it without complaining, even though
-                # we ignore it.
-                if ($version >= NaturalDocs::Version->FromString('1.32'))
-                    {
-                    NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                    };
-                }
-            else
-                {  $language->SetPackageSeparator($value);  };
-            }
-
-        elsif ($keyword =~ /^(?:(add|replace) )?ignored? (?:(.+) )?prefix(?:es)? in index$/)
-            {
-            my ($command, $topicName) = ($1, $2);
-            my $topicType;
-
-            if ($topicName)
-                {
-                if (!( ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName) ))
-                    {
-                    NaturalDocs::ConfigFile->AddError($topicName . ' is not a defined topic type.', $lineNumber);
-                    };
-                }
-            else
-                {  $topicType = ::TOPIC_GENERAL();  };
-
-            if ($topicType)
-                {
-                my @prefixes;
-
-                if (defined $language->IgnoredPrefixesFor($topicType))
-                    {
-                    if ($command eq 'add')
-                        {  @prefixes = @{$language->IgnoredPrefixesFor($topicType)};  }
-                    elsif (!$command)
-                        {
-                        NaturalDocs::ConfigFile->AddError('You need to specify whether you are adding to or replacing the list of '
-                                                                         . 'ignored prefixes.', $lineNumber);
-                        };
-                    };
-
-                push @prefixes, split(/ /, $value);
-                $language->SetIgnoredPrefixesFor($topicType, \@prefixes);
-                };
-            }
-
-        elsif ($keyword eq 'full language support' || $keyword eq 'perl package')
-            {
-            if ($languageKeyword eq 'alter language')
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot use ' . $keyword . ' with Alter Language.', $lineNumber);
-                };
-            # else ignore it.
-            }
-
-        elsif ($keyword =~ /^line comments?$/)
-            {
-            if ($fullLanguageSupport)
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                }
-            else
-                {
-                my @symbols = split(/ /, $value);
-                $language->SetLineCommentSymbols(\@symbols);
-                };
-            }
-
-        elsif ($keyword =~ /^block comments?$/)
-            {
-            if ($fullLanguageSupport)
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                }
-            else
-                {
-                my @symbols = split(/ /, $value);
-
-                if ((scalar @symbols) % 2 == 0)
-                    {  $language->SetBlockCommentSymbols(\@symbols);  }
-                else
-                    {  NaturalDocs::ConfigFile->AddError('Block comment symbols must appear in pairs.', $lineNumber);  };
-                };
-            }
-
-        elsif ($keyword =~ /^(?:(.+) )?prototype enders?$/)
-            {
-            if ($fullLanguageSupport)
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                }
-            else
-                {
-                my $topicName = $1;
-                my $topicType;
-
-                if ($topicName)
-                    {
-                    if (!( ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName) ))
-                        {
-                        NaturalDocs::ConfigFile->AddError($topicName . ' is not a defined topic type.', $lineNumber);
-                        };
-                    }
-                else
-                    {  $topicType = ::TOPIC_GENERAL();  };
-
-                if ($topicType)
-                    {
-                    $value =~ s/\\n/\n/g;
-                    my @symbols = split(/ /, $value);
-                    $language->SetPrototypeEndersFor($topicType, \@symbols);
-                    };
-                };
-            }
-
-        elsif ($keyword eq 'line extender')
-            {
-            if ($fullLanguageSupport)
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                }
-            else
-                {
-                $language->SetLineExtender($value);
-                };
-            }
-
-        elsif ($keyword eq 'enum values')
-            {
-            if ($fullLanguageSupport)
-                {
-                NaturalDocs::ConfigFile->AddError('You cannot define this property when using full language support.', $lineNumber);
-                }
-            else
-                {
-                $value = lc($value);
-                my $constant;
-
-                if ($value eq 'global')
-                    {  $constant = ::ENUM_GLOBAL();  }
-                elsif ($value eq 'under type')
-                    {  $constant = ::ENUM_UNDER_TYPE();  }
-                elsif ($value eq 'under parent')
-                    {  $constant = ::ENUM_UNDER_PARENT();  };
-
-                if (defined $value)
-                    {  $language->SetEnumValues($constant);  }
-                else
-                    {
-                    NaturalDocs::ConfigFile->AddError('Enum Values must be "Global", "Under Type", or "Under Parent".', $lineNumber);
-                    };
-                };
-            }
-
-        else
-            {
-            NaturalDocs::ConfigFile->AddError($keyword . ' is not a valid keyword.', $lineNumber);
-            };
-        };
-    };
-
-
-#
-#   Function: Save
-#
-#   Saves the main and user versions of <Languages.txt>.
-#
-sub Save
-    {
-    my $self = shift;
-
-    $self->SaveFile(1); # Main
-    $self->SaveFile(0); # User
-    };
-
-
-#
-#   Function: SaveFile
-#
-#   Saves a particular version of <Topics.txt>.
-#
-#   Parameters:
-#
-#       isMain - Whether the file is the main file or not.
-#
-sub SaveFile #(isMain)
-    {
-    my ($self, $isMain) = @_;
-
-    my $file;
-
-    if ($isMain)
-        {
-        if (NaturalDocs::Project->MainLanguagesFileStatus() == ::FILE_SAME())
-            {  return;  };
-        $file = NaturalDocs::Project->MainLanguagesFile();
-        }
-    else
-        {
-        # Have to check the main too because this file lists the languages defined there.
-        if (NaturalDocs::Project->UserLanguagesFileStatus() == ::FILE_SAME() &&
-            NaturalDocs::Project->MainLanguagesFileStatus() == ::FILE_SAME())
-            {  return;  };
-        $file = NaturalDocs::Project->UserLanguagesFile();
-        };
-
-
-    # Array of segments, with each being groups of three consecutive entries.  The first is the keyword ('language' or
-    # 'alter language'), the second is the value, and the third is a hashref of all the properties.
-    # - For properties that can accept a topic type, the property values are hashrefs mapping topic types to the values.
-    # - For properties that can accept 'add' or 'replace', there is an additional property ending in 'command' that stores it.
-    # - For properties that can accept both, the 'command' thing is applied to the topic types rather than the properties.
-    my @segments;
-
-    my @ignoredExtensions;
-
-    my $currentProperties;
-    my $version;
-
-    if ($version = NaturalDocs::ConfigFile->Open($file))
-        {
-        # We can assume the file is valid.
-
-        while (my ($keyword, $value, $comment) = NaturalDocs::ConfigFile->GetLine())
-            {
-            $value .= $comment;
-            $value =~ s/^ //;
-
-            if ($keyword eq 'language')
-                {
-                $currentProperties = { };
-
-                # Case is important with these two.
-                if (lc($value) eq 'shebang script')
-                    {  $value = 'Shebang Script';  }
-                elsif (lc($value) eq 'text file')
-                    {  $value = 'Text File';  };
-
-                push @segments, 'language', $value, $currentProperties;
-                }
-
-            elsif ($keyword eq 'alter language')
-                {
-                $currentProperties = { };
-                push @segments, 'alter language', $languages{lc($value)}->Name(), $currentProperties;
-                }
-
-            elsif ($keyword =~ /^ignored? extensions?$/)
-                {
-                $value =~ tr/*.//d;
-                push @ignoredExtensions, split(/ /, $value);
-                }
-
-            elsif ($keyword eq 'package separator' || $keyword eq 'full language support' || $keyword eq 'perl package' ||
-                    $keyword eq 'line extender' || $keyword eq 'enum values')
-                {
-                $currentProperties->{$keyword} = $value;
-                }
-
-            elsif ($keyword =~ /^line comments?$/)
-                {
-                $currentProperties->{'line comments'} = $value;
-                }
-            elsif ($keyword =~ /^block comments?$/)
-                {
-                $currentProperties->{'block comments'} = $value;
-                }
-
-            elsif ($keyword =~ /^(?:(add|replace) )?extensions?$/)
-                {
-                my $command = $1;
-
-                if ($command eq 'add' && exists $currentProperties->{'extensions'})
-                    {  $currentProperties->{'extensions'} .= ' ' . $value;  }
-                else
-                    {
-                    $currentProperties->{'extensions'} = $value;
-                    $currentProperties->{'extensions command'} = $command;
-                    };
-                }
-
-            elsif ($keyword =~ /^(?:(add|replace) )?shebang strings?$/)
-                {
-                my $command = $1;
-
-                if ($command eq 'add' && exists $currentProperties->{'shebang strings'})
-                    {  $currentProperties->{'shebang strings'} .= ' ' . $value;  }
-                else
-                    {
-                    $currentProperties->{'shebang strings'} = $value;
-                    $currentProperties->{'shebang strings command'} = $command;
-                    };
-                }
-
-            elsif ($keyword =~ /^(?:(.+) )?prototype enders?$/)
-                {
-                my $topicName = $1;
-                my $topicType;
-
-                if ($topicName)
-                    {  ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName);  }
-                else
-                    {  $topicType = ::TOPIC_GENERAL();  };
-
-                my $currentTypeProperties = $currentProperties->{'prototype enders'};
-
-                if (!defined $currentTypeProperties)
-                    {
-                    $currentTypeProperties = { };
-                    $currentProperties->{'prototype enders'} = $currentTypeProperties;
-                    };
-
-                $currentTypeProperties->{$topicType} = $value;
-                }
-
-            elsif ($keyword =~ /^(?:(add|replace) )?ignored? (?:(.+) )?prefix(?:es)? in index$/)
-                {
-                my ($command, $topicName) = ($1, $2);
-                my $topicType;
-
-                if ($topicName)
-                    {  ($topicType, undef) = NaturalDocs::Topics->NameInfo($topicName);  }
-                else
-                    {  $topicType = ::TOPIC_GENERAL();  };
-
-                my $currentTypeProperties = $currentProperties->{'ignored prefixes in index'};
-
-                if (!defined $currentTypeProperties)
-                    {
-                    $currentTypeProperties = { };
-                    $currentProperties->{'ignored prefixes in index'} = $currentTypeProperties;
-                    };
-
-                if ($command eq 'add' && exists $currentTypeProperties->{$topicType})
-                    {  $currentTypeProperties->{$topicType} .= ' ' . $value;  }
-                else
-                    {
-                    $currentTypeProperties->{$topicType} = $value;
-                    $currentTypeProperties->{$topicType . ' command'} = $command;
-                    };
-                };
-            };
-
-        NaturalDocs::ConfigFile->Close();
-        };
-
-
-    if (!open(FH_LANGUAGES, '>' . $file))
-        {
-        # The main file may be on a shared volume or some other place the user doesn't have write access to.  Since this is only to
-        # reformat the file, we can ignore the failure.
-        if ($isMain)
-            {  return;  }
-        else
-            {  die "Couldn't save " . $file;  };
-        };
-
-    print FH_LANGUAGES 'Format: ' . NaturalDocs::Settings->TextAppVersion() . "\n\n";
-
-    # Remember the 80 character limit.
-
-    if ($isMain)
-        {
-        print FH_LANGUAGES
-        "# This is the main Natural Docs languages file.  If you change anything here,\n"
-        . "# it will apply to EVERY PROJECT you use Natural Docs on.  If you'd like to\n"
-        . "# change something for just one project, edit the Languages.txt in its project\n"
-        . "# directory instead.\n";
-        }
-    else
-        {
-        print FH_LANGUAGES
-        "# This is the Natural Docs languages file for this project.  If you change\n"
-        . "# anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change\n"
-        . "# something for all your projects, edit the Languages.txt in Natural Docs'\n"
-        . "# Config directory instead.\n\n\n";
-
-        if (scalar @ignoredExtensions == 1)
-            {
-            print FH_LANGUAGES
-            'Ignore Extension: ' . $ignoredExtensions[0] . "\n";
-            }
-        elsif (scalar @ignoredExtensions)
-            {
-            print FH_LANGUAGES
-            'Ignore Extensions: ' . join(' ', @ignoredExtensions) . "\n";
-            }
-        else
-            {
-            print FH_LANGUAGES
-            "# You can prevent certain file extensions from being scanned like this:\n"
-            . "# Ignore Extensions: [extension] [extension] ...\n"
-            };
-        };
-
-    print FH_LANGUAGES
-    "\n\n"
-    . "#-------------------------------------------------------------------------------\n"
-    . "# SYNTAX:\n"
-    . "#\n"
-    . "# Unlike other Natural Docs configuration files, in this file all comments\n"
-    . "# MUST be alone on a line.  Some languages deal with the # character, so you\n"
-    . "# cannot put comments on the same line as content.\n"
-    . "#\n"
-    . "# Also, all lists are separated with spaces, not commas, again because some\n"
-    . "# languages may need to use them.\n"
-    . "#\n";
-
-    if ($isMain)
-        {
-        print FH_LANGUAGES
-        "# Language: [name]\n"
-        . "#    Defines a new language.  Its name can use any characters.\n"
-        . "#\n";
-        }
-    else
-        {
-        print FH_LANGUAGES
-        "# Language: [name]\n"
-        . "# Alter Language: [name]\n"
-        . "#    Defines a new language or alters an existing one.  Its name can use any\n"
-        . "#    characters.  If any of the properties below have an add/replace form, you\n"
-        . "#    must use that when using Alter Language.\n"
-        . "#\n";
-        };
-
-    print FH_LANGUAGES
-    "#    The language Shebang Script is special.  It's entry is only used for\n"
-    . "#    extensions, and files with those extensions have their shebang (#!) lines\n"
-    . "#    read to determine the real language of the file.  Extensionless files are\n"
-    . "#    always treated this way.\n"
-    . "#\n"
-    . "#    The language Text File is also special.  It's treated as one big comment\n"
-    . "#    so you can put Natural Docs content in them without special symbols.  Also,\n"
-    . "#    if you don't specify a package separator, ignored prefixes, or enum value\n"
-    . "#    behavior, it will copy those settings from the language that is used most\n"
-    . "#    in the source tree.\n"
-    . "#\n"
-    . "# Extensions: [extension] [extension] ...\n";
-
-    if ($isMain)
-        {
-        print FH_LANGUAGES
-        "#    Defines the file extensions of the language's source files.  You can use *\n"
-        . "#    to mean any undefined extension.\n"
-        . "#\n"
-        . "# Shebang Strings: [string] [string] ...\n"
-        . "#    Defines a list of strings that can appear in the shebang (#!) line to\n"
-        . "#    designate that it's part of the language.\n"
-        . "#\n";
-        }
-    else
-        {
-        print FH_LANGUAGES
-        "# [Add/Replace] Extensions: [extension] [extension] ...\n"
-        . "#    Defines the file extensions of the language's source files.  You can\n"
-        . "#    redefine extensions found in the main languages file.  You can use * to\n"
-        . "#    mean any undefined extension.\n"
-        . "#\n"
-        . "# Shebang Strings: [string] [string] ...\n"
-        . "# [Add/Replace] Shebang Strings: [string] [string] ...\n"
-        . "#    Defines a list of strings that can appear in the shebang (#!) line to\n"
-        . "#    designate that it's part of the language.  You can redefine strings found\n"
-        . "#    in the main languages file.\n"
-        . "#\n";
-        };
-
-    print FH_LANGUAGES
-    "# Ignore Prefixes in Index: [prefix] [prefix] ...\n"
-    . (!$isMain ? "# [Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...\n#\n" : '')
-    . "# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n"
-    . (!$isMain ? "# [Add/Replace] Ignored [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n" : '')
-    . "#    Specifies prefixes that should be ignored when sorting symbols in an\n"
-    . "#    index.  Can be specified in general or for a specific topic type.\n"
-    . "#\n"
-    . "#------------------------------------------------------------------------------\n"
-    . "# For basic language support only:\n"
-    . "#\n"
-    . "# Line Comments: [symbol] [symbol] ...\n"
-    . "#    Defines a space-separated list of symbols that are used for line comments,\n"
-    . "#    if any.\n"
-    . "#\n"
-    . "# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ...\n"
-    . "#    Defines a space-separated list of symbol pairs that are used for block\n"
-    . "#    comments, if any.\n"
-    . "#\n"
-    . "# Package Separator: [symbol]\n"
-    . "#    Defines the default package separator symbol.  The default is a dot.\n"
-    . "#\n"
-    . "# [Topic Type] Prototype Enders: [symbol] [symbol] ...\n"
-    . "#    When defined, Natural Docs will attempt to get a prototype from the code\n"
-    . "#    immediately following the topic type.  It stops when it reaches one of\n"
-    . "#    these symbols.  Use \\n for line breaks.\n"
-    . "#\n"
-    . "# Line Extender: [symbol]\n"
-    . "#    Defines the symbol that allows a prototype to span multiple lines if\n"
-    . "#    normally a line break would end it.\n"
-    . "#\n"
-    . "# Enum Values: [global|under type|under parent]\n"
-    . "#    Defines how enum values are referenced.  The default is global.\n"
-    . "#    global       - Values are always global, referenced as 'value'.\n"
-    . "#    under type   - Values are under the enum type, referenced as\n"
-    . "#               'package.enum.value'.\n"
-    . "#    under parent - Values are under the enum's parent, referenced as\n"
-    . "#               'package.value'.\n"
-    . "#\n"
-    . "# Perl Package: [perl package]\n"
-    . "#    Specifies the Perl package used to fine-tune the language behavior in ways\n"
-    . "#    too complex to do in this file.\n"
-    . "#\n"
-    . "#------------------------------------------------------------------------------\n"
-    . "# For full language support only:\n"
-    . "#\n"
-    . "# Full Language Support: [perl package]\n"
-    . "#    Specifies the Perl package that has the parsing routines necessary for full\n"
-    . "#    language support.\n"
-    . "#\n"
-    . "#-------------------------------------------------------------------------------\n\n";
-
-    if ($isMain)
-        {
-        print FH_LANGUAGES
-        "# The following languages MUST be defined in this file:\n"
-        . "#\n"
-        . "#    Text File, Shebang Script\n";
-        }
-    else
-        {
-        print FH_LANGUAGES
-        "# The following languages are defined in the main file, if you'd like to alter\n"
-        . "# them:\n"
-        . "#\n"
-        . Text::Wrap::wrap('#    ', '#    ', join(', ', @mainLanguageNames)) . "\n";
-        };
-
-    print FH_LANGUAGES "\n"
-    . "# If you add a language that you think would be useful to other developers\n"
-    . "# and should be included in Natural Docs by default, please e-mail it to\n"
-    . "# languages [at] naturaldocs [dot] org.\n";
-
-    my @topicTypeOrder = ( ::TOPIC_GENERAL(), ::TOPIC_CLASS(), ::TOPIC_FUNCTION(), ::TOPIC_VARIABLE(),
-                                         ::TOPIC_PROPERTY(), ::TOPIC_TYPE(), ::TOPIC_CONSTANT() );
-
-    for (my $i = 0; $i < scalar @segments; $i += 3)
-        {
-        my ($keyword, $name, $properties) = @segments[$i..$i+2];
-
-        print FH_LANGUAGES "\n\n";
-
-        if ($keyword eq 'language')
-            {  print FH_LANGUAGES 'Language: ' . $name . "\n\n";  }
-        else
-            {  print FH_LANGUAGES 'Alter Language: ' . $name . "\n\n";  };
-
-        if (exists $properties->{'extensions'})
-            {
-            print FH_LANGUAGES '   ';
-
-            if ($properties->{'extensions command'})
-                {  print FH_LANGUAGES ucfirst($properties->{'extensions command'}) . ' ';  };
-
-            my @extensions = split(/ /, $properties->{'extensions'}, 2);
-
-            if (scalar @extensions == 1)
-                {  print FH_LANGUAGES 'Extension: ';  }
-            else
-                {  print FH_LANGUAGES 'Extensions: ';  };
-
-            print FH_LANGUAGES lc($properties->{'extensions'}) . "\n";
-            };
-
-        if (exists $properties->{'shebang strings'})
-            {
-            print FH_LANGUAGES '   ';
-
-            if ($properties->{'shebang strings command'})
-                {  print FH_LANGUAGES ucfirst($properties->{'shebang strings command'}) . ' ';  };
-
-            my @shebangStrings = split(/ /, $properties->{'shebang strings'}, 2);
-
-            if (scalar @shebangStrings == 1)
-                {  print FH_LANGUAGES 'Shebang String: ';  }
-            else
-                {  print FH_LANGUAGES 'Shebang Strings: ';  };
-
-            print FH_LANGUAGES lc($properties->{'shebang strings'}) . "\n";
-            };
-
-        if (exists $properties->{'ignored prefixes in index'})
-            {
-            my $topicTypePrefixes = $properties->{'ignored prefixes in index'};
-
-            my %usedTopicTypes;
-            my @topicTypes = ( @topicTypeOrder, keys %$topicTypePrefixes );
-
-            foreach my $topicType (@topicTypes)
-                {
-                if ($topicType !~ / command$/ &&
-                    exists $topicTypePrefixes->{$topicType} &&
-                    !exists $usedTopicTypes{$topicType})
-                    {
-                    print FH_LANGUAGES '   ';
-
-                    if ($topicTypePrefixes->{$topicType . ' command'})
-                        {  print FH_LANGUAGES ucfirst($topicTypePrefixes->{$topicType . ' command'}) . ' Ignored ';  }
-                    else
-                        {  print FH_LANGUAGES 'Ignore ';  };
-
-                    if ($topicType ne ::TOPIC_GENERAL())
-                        {  print FH_LANGUAGES NaturalDocs::Topics->TypeInfo($topicType)->Name() . ' ';  };
-
-                    my @prefixes = split(/ /, $topicTypePrefixes->{$topicType}, 2);
-
-                    if (scalar @prefixes == 1)
-                        {  print FH_LANGUAGES 'Prefix in Index: ';  }
-                    else
-                        {  print FH_LANGUAGES 'Prefixes in Index: ';  };
-
-                    print FH_LANGUAGES $topicTypePrefixes->{$topicType} . "\n";
-
-                    $usedTopicTypes{$topicType} = 1;
-                    };
-                };
-            };
-
-        if (exists $properties->{'line comments'})
-            {
-            my @comments = split(/ /, $properties->{'line comments'}, 2);
-
-            if (scalar @comments == 1)
-                {  print FH_LANGUAGES '   Line Comment: ';  }
-            else
-                {  print FH_LANGUAGES '   Line Comments: ';  };
-
-            print FH_LANGUAGES $properties->{'line comments'} . "\n";
-            };
-
-        if (exists $properties->{'block comments'})
-            {
-            my @comments = split(/ /, $properties->{'block comments'}, 3);
-
-            if (scalar @comments == 2)
-                {  print FH_LANGUAGES '   Block Comment: ';  }
-            else
-                {  print FH_LANGUAGES '   Block Comments: ';  };
-
-            print FH_LANGUAGES $properties->{'block comments'} . "\n";
-            };
-
-        if (exists $properties->{'package separator'})
-            {
-            # Prior to 1.32, Package Separator was allowed for full language support.  Ignore it when reformatting.
-            if ($version >= NaturalDocs::Version->FromString('1.32') || !exists $properties->{'full language support'})
-                {  print FH_LANGUAGES '   Package Separator: ' . $properties->{'package separator'} . "\n";  };
-            };
-
-        if (exists $properties->{'enum values'})
-            {
-            print FH_LANGUAGES '   Enum Values: ' . ucfirst(lc($properties->{'enum values'})) . "\n";
-            };
-
-        if (exists $properties->{'prototype enders'})
-            {
-            my $topicTypeEnders = $properties->{'prototype enders'};
-
-            my %usedTopicTypes;
-            my @topicTypes = ( @topicTypeOrder, keys %$topicTypeEnders );
-
-            foreach my $topicType (@topicTypes)
-                {
-                if ($topicType !~ / command$/ &&
-                    exists $topicTypeEnders->{$topicType} &&
-                    !exists $usedTopicTypes{$topicType})
-                    {
-                    print FH_LANGUAGES '   ';
-
-                    if ($topicType ne ::TOPIC_GENERAL())
-                        {  print FH_LANGUAGES NaturalDocs::Topics->TypeInfo($topicType)->Name() . ' ';  };
-
-                    my @enders = split(/ /, $topicTypeEnders->{$topicType}, 2);
-
-                    if (scalar @enders == 1)
-                        {  print FH_LANGUAGES 'Prototype Ender: ';  }
-                    else
-                        {  print FH_LANGUAGES 'Prototype Enders: ';  };
-
-                    print FH_LANGUAGES $topicTypeEnders->{$topicType} . "\n";
-
-                    $usedTopicTypes{$topicType} = 1;
-                    };
-                };
-            };
-
-        if (exists $properties->{'line extender'})
-            {
-            print FH_LANGUAGES '   Line Extender: ' . $properties->{'line extender'} . "\n";
-            };
-
-        if (exists $properties->{'perl package'})
-            {
-            print FH_LANGUAGES '   Perl Package: ' . $properties->{'perl package'} . "\n";
-            };
-
-        if (exists $properties->{'full language support'})
-            {
-            print FH_LANGUAGES '   Full Language Support: ' . $properties->{'full language support'} . "\n";
-            };
-        };
-
-    close(FH_LANGUAGES);
-    };
-
-
-
-###############################################################################
-# Group: Functions
-
-
-#
-#   Function: LanguageOf
-#
-#   Returns the language of the passed source file.
-#
-#   Parameters:
-#
-#       sourceFile - The source <FileName> to get the language of.
-#
-#   Returns:
-#
-#       A <NaturalDocs::Languages::Base>-derived object for the passed file, or undef if the file is not a recognized language.
-#
-sub LanguageOf #(sourceFile)
-    {
-    my ($self, $sourceFile) = @_;
-
-    my $extension = NaturalDocs::File->ExtensionOf($sourceFile);
-    if (defined $extension)
-        {  $extension = lc($extension);  };
-
-    my $languageName;
-
-    if (!defined $extension)
-        {  $languageName = 'shebang script';  }
-    else
-        {  $languageName = $extensions{$extension};  };
-
-    if (!defined $languageName)
-        {  $languageName = $extensions{'*'};  };
-
-    if (defined $languageName)
-        {
-        if ($languageName eq 'shebang script')
-            {
-            if (exists $shebangFiles{$sourceFile})
-                {
-                if (defined $shebangFiles{$sourceFile})
-                    {  return $languages{$shebangFiles{$sourceFile}};  }
-                else
-                    {  return undef;  };
-                }
-
-            else # (!exists $shebangFiles{$sourceFile})
-                {
-                my $shebangLine;
-
-                open(SOURCEFILEHANDLE, '<' . $sourceFile) or die 'Could not open ' . $sourceFile;
-
-                read(SOURCEFILEHANDLE, $shebangLine, 2);
-                if ($shebangLine eq '#!')
-                    {  $shebangLine = <SOURCEFILEHANDLE>;  }
-                else
-                    {  $shebangLine = undef;  };
-
-                close (SOURCEFILEHANDLE);
-
-                if (!defined $shebangLine)
-                    {
-                    $shebangFiles{$sourceFile} = undef;
-                    return undef;
-                    }
-                else
-                    {
-                    $shebangLine = lc($shebangLine);
-
-                    foreach my $shebangString (keys %shebangStrings)
-                        {
-                        if (index($shebangLine, $shebangString) != -1)
-                            {
-                            $shebangFiles{$sourceFile} = $shebangStrings{$shebangString};
-                            return $languages{$shebangStrings{$shebangString}};
-                            };
-                        };
-
-                    $shebangFiles{$sourceFile} = undef;
-                    return undef;
-                    };
-                };
-            }
-
-        else # language name ne 'shebang script'
-            {  return $languages{$languageName};  };
-        }
-    else # !defined $language
-        {
-        return undef;
-        };
-    };
-
-
-#
-#   Function: OnMostUsedLanguageKnown
-#
-#   Called when the most used language is known.
-#
-sub OnMostUsedLanguageKnown
-    {
-    my $self = shift;
-
-    my $language = $languages{lc( NaturalDocs::Project->MostUsedLanguage() )};
-
-    if ($language)
-        {
-        if (!$languages{'text file'}->HasIgnoredPrefixes())
-            {  $languages{'text file'}->CopyIgnoredPrefixesOf($language);  };
-        if (!$languages{'text file'}->PackageSeparatorWasSet())
-            {  $languages{'text file'}->SetPackageSeparator($language->PackageSeparator());  };
-        if (!$languages{'text file'}->EnumValuesWasSet())
-            {  $languages{'text file'}->SetEnumValues($language->EnumValues());  };
-        };
-    };
-
-
-1;