bixbite 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/VERSION +1 -0
- data/bin/bixbite +73 -0
- data/lib/bixbite.rb +13 -0
- data/lib/bixbite/command.rb +14 -0
- data/lib/bixbite/create.rb +76 -0
- data/template/Rakefile +25 -0
- data/template/assets/bixbite/Rakefile.rb +297 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
- data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
- data/template/assets/utilities/pngout +0 -0
- data/template/deploy/public_html/.htaccess +0 -0
- data/template/documentation/js/.htaccess +0 -0
- data/template/src/html/.htaccess +76 -0
- data/template/src/html/css/cmn/global.css +96 -0
- data/template/src/html/css/cmn/ie.css +15 -0
- data/template/src/html/css/cmn/ie6.css +15 -0
- data/template/src/html/images/cmn/.htaccess +0 -0
- data/template/src/html/images/tmp/.htaccess +0 -0
- data/template/src/html/includes/debug.inc +5 -0
- data/template/src/html/includes/footer.inc +52 -0
- data/template/src/html/includes/header.inc +61 -0
- data/template/src/html/includes/html.inc +3 -0
- data/template/src/html/includes/namespace.inc +19 -0
- data/template/src/html/includes/page.inc +151 -0
- data/template/src/html/index.html +35 -0
- data/template/src/html/js/cmn/bootstrap.js +74 -0
- data/template/src/html/js/cmn/global.js +142 -0
- data/template/src/html/js/cmn/lib/LAB.js +348 -0
- data/template/src/html/min/.htaccess +4 -0
- data/template/src/html/min/MinifyCLI.php +19 -0
- data/template/src/html/min/README.txt +132 -0
- data/template/src/html/min/builder/_index.js +242 -0
- data/template/src/html/min/builder/bm.js +36 -0
- data/template/src/html/min/builder/index.php +182 -0
- data/template/src/html/min/builder/ocCheck.php +36 -0
- data/template/src/html/min/builder/rewriteTest.js +1 -0
- data/template/src/html/min/config.php +187 -0
- data/template/src/html/min/groupsConfig.php +34 -0
- data/template/src/html/min/index.php +66 -0
- data/template/src/html/min/lib/FirePHP.php +1370 -0
- data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
- data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
- data/template/src/html/min/lib/JSMin.php +314 -0
- data/template/src/html/min/lib/JSMinPlus.php +1872 -0
- data/template/src/html/min/lib/Minify.php +532 -0
- data/template/src/html/min/lib/Minify/Build.php +103 -0
- data/template/src/html/min/lib/Minify/CSS.php +83 -0
- data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
- data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
- data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
- data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
- data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
- data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
- data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
- data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
- data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
- data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
- data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
- data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
- data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
- data/template/src/html/min/lib/Minify/HTML.php +245 -0
- data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
- data/template/src/html/min/lib/Minify/Lines.php +131 -0
- data/template/src/html/min/lib/Minify/Logger.php +45 -0
- data/template/src/html/min/lib/Minify/Packer.php +37 -0
- data/template/src/html/min/lib/Minify/Source.php +187 -0
- data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
- data/template/src/html/min/lib/Solar/Dir.php +199 -0
- data/template/src/html/min/lib/closure-compiler.jar +0 -0
- data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
- data/template/src/html/min/utils.php +90 -0
- data/template/src/templates/css/template.css +7 -0
- data/template/src/templates/js/template.js +72 -0
- data/template/src/templates/template.html +18 -0
- data/template/src/yaml/config.yml +46 -0
- data/template/src/yaml/deploy.yml +35 -0
- data/test/bixbite_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +278 -0
@@ -0,0 +1,201 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::Menu::Entry
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A class representing an entry in the menu.
|
8
|
+
#
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
12
|
+
# Natural Docs is licensed under the GPL
|
13
|
+
|
14
|
+
use strict;
|
15
|
+
use integer;
|
16
|
+
|
17
|
+
package NaturalDocs::Menu::Entry;
|
18
|
+
|
19
|
+
|
20
|
+
###############################################################################
|
21
|
+
# Group: Implementation
|
22
|
+
|
23
|
+
#
|
24
|
+
# Constants: Members
|
25
|
+
#
|
26
|
+
# The object is implemented as a blessed arrayref with the indexes below.
|
27
|
+
#
|
28
|
+
# TYPE - The <MenuEntryType>
|
29
|
+
# TITLE - The title of the entry.
|
30
|
+
# TARGET - The target of the entry. If the type is <MENU_FILE>, it will be the source <FileName>. If the type is
|
31
|
+
# <MENU_LINK>, it will be the URL. If the type is <MENU_GROUP>, it will be an arrayref of
|
32
|
+
# <NaturalDocs::Menu::Entry> objects representing the group's content. If the type is <MENU_INDEX>, it will be
|
33
|
+
# a <TopicType>.
|
34
|
+
# FLAGS - Any <Menu Entry Flags> that apply.
|
35
|
+
#
|
36
|
+
use constant TYPE => 0;
|
37
|
+
use constant TITLE => 1;
|
38
|
+
use constant TARGET => 2;
|
39
|
+
use constant FLAGS => 3;
|
40
|
+
# DEPENDENCY: New() depends on the order of these constants.
|
41
|
+
|
42
|
+
|
43
|
+
###############################################################################
|
44
|
+
# Group: Functions
|
45
|
+
|
46
|
+
#
|
47
|
+
# Function: New
|
48
|
+
#
|
49
|
+
# Creates and returns a new object.
|
50
|
+
#
|
51
|
+
# Parameters:
|
52
|
+
#
|
53
|
+
# type - The <MenuEntryType>.
|
54
|
+
# title - The title of the entry.
|
55
|
+
# target - The target of the entry, if applicable. If the type is <MENU_FILE>, use the source <FileName>. If the type is
|
56
|
+
# <MENU_LINK>, use the URL. If the type is <MENU_INDEX>, use the <TopicType>. Otherwise set it to undef.
|
57
|
+
# flags - Any <Menu Entry Flags> that apply.
|
58
|
+
#
|
59
|
+
sub New #(type, title, target, flags)
|
60
|
+
{
|
61
|
+
# DEPENDENCY: This gode depends on the order of the constants.
|
62
|
+
|
63
|
+
my $package = shift;
|
64
|
+
|
65
|
+
my $object = [ @_ ];
|
66
|
+
bless $object, $package;
|
67
|
+
|
68
|
+
if ($object->[TYPE] == ::MENU_GROUP())
|
69
|
+
{ $object->[TARGET] = [ ]; };
|
70
|
+
if (!defined $object->[FLAGS])
|
71
|
+
{ $object->[FLAGS] = 0; };
|
72
|
+
|
73
|
+
return $object;
|
74
|
+
};
|
75
|
+
|
76
|
+
|
77
|
+
# Function: Type
|
78
|
+
# Returns the <MenuEntryType>.
|
79
|
+
sub Type
|
80
|
+
{ return $_[0]->[TYPE]; };
|
81
|
+
|
82
|
+
# Function: Title
|
83
|
+
# Returns the title of the entry.
|
84
|
+
sub Title
|
85
|
+
{ return $_[0]->[TITLE]; };
|
86
|
+
|
87
|
+
# Function: SetTitle
|
88
|
+
# Replaces the entry's title.
|
89
|
+
sub SetTitle #(title)
|
90
|
+
{ $_[0]->[TITLE] = $_[1]; };
|
91
|
+
|
92
|
+
#
|
93
|
+
# Function: Target
|
94
|
+
#
|
95
|
+
# Returns the target of the entry, if applicable. If the type is <MENU_FILE>, it returns the source <FileName>. If the type is
|
96
|
+
# <MENU_LINK>, it returns the URL. If the type is <MENU_INDEX>, it returns the <TopicType>. Otherwise it returns undef.
|
97
|
+
#
|
98
|
+
sub Target
|
99
|
+
{
|
100
|
+
my $self = shift;
|
101
|
+
|
102
|
+
# Group entries are the only time when target won't be undef when it should be.
|
103
|
+
if ($self->Type() == ::MENU_GROUP())
|
104
|
+
{ return undef; }
|
105
|
+
else
|
106
|
+
{ return $self->[TARGET]; };
|
107
|
+
};
|
108
|
+
|
109
|
+
# Function: SetTarget
|
110
|
+
# Replaces the entry's target.
|
111
|
+
sub SetTarget #(target)
|
112
|
+
{ $_[0]->[TARGET] = $_[1]; };
|
113
|
+
|
114
|
+
# Function: Flags
|
115
|
+
# Returns the <Menu Entry Flags>.
|
116
|
+
sub Flags
|
117
|
+
{ return $_[0]->[FLAGS]; };
|
118
|
+
|
119
|
+
# Function: SetFlags
|
120
|
+
# Replaces the <Menu Entry Flags>.
|
121
|
+
sub SetFlags #(flags)
|
122
|
+
{ $_[0]->[FLAGS] = $_[1]; };
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
###############################################################################
|
127
|
+
# Group: Group Functions
|
128
|
+
#
|
129
|
+
# All of these functions assume the type is <MENU_GROUP>. Do *not* call any of these without checking <Type()> first.
|
130
|
+
|
131
|
+
|
132
|
+
#
|
133
|
+
# Function: GroupContent
|
134
|
+
#
|
135
|
+
# Returns an arrayref of <NaturalDocs::Menu::Entry> objects representing the contents of the
|
136
|
+
# group, or undef otherwise. This arrayref will always exist for <MENU_GROUP>'s and can be changed.
|
137
|
+
#
|
138
|
+
sub GroupContent
|
139
|
+
{
|
140
|
+
return $_[0]->[TARGET];
|
141
|
+
};
|
142
|
+
|
143
|
+
|
144
|
+
#
|
145
|
+
# Function: GroupIsEmpty
|
146
|
+
#
|
147
|
+
# If the type is <MENU_GROUP>, returns whether the group is empty.
|
148
|
+
#
|
149
|
+
sub GroupIsEmpty
|
150
|
+
{
|
151
|
+
my $self = shift;
|
152
|
+
return (scalar @{$self->GroupContent()} > 0);
|
153
|
+
};
|
154
|
+
|
155
|
+
|
156
|
+
#
|
157
|
+
# Function: PushToGroup
|
158
|
+
#
|
159
|
+
# Pushes the entry to the end of the group content.
|
160
|
+
#
|
161
|
+
sub PushToGroup #(entry)
|
162
|
+
{
|
163
|
+
my ($self, $entry) = @_;
|
164
|
+
push @{$self->GroupContent()}, $entry;
|
165
|
+
};
|
166
|
+
|
167
|
+
|
168
|
+
#
|
169
|
+
# Function: DeleteFromGroup
|
170
|
+
#
|
171
|
+
# Deletes an entry from the group content by index.
|
172
|
+
#
|
173
|
+
sub DeleteFromGroup #(index)
|
174
|
+
{
|
175
|
+
my ($self, $index) = @_;
|
176
|
+
|
177
|
+
my $groupContent = $self->GroupContent();
|
178
|
+
|
179
|
+
splice( @$groupContent, $index, 1 );
|
180
|
+
};
|
181
|
+
|
182
|
+
|
183
|
+
#
|
184
|
+
# Function: MarkEndOfOriginal
|
185
|
+
#
|
186
|
+
# If the group doesn't already have one, adds a <MENU_ENDOFORIGINAL> entry to the end and sets the
|
187
|
+
# <MENU_GROUP_HASENDOFORIGINAL> flag.
|
188
|
+
#
|
189
|
+
sub MarkEndOfOriginal
|
190
|
+
{
|
191
|
+
my $self = shift;
|
192
|
+
|
193
|
+
if (($self->Flags() & ::MENU_GROUP_HASENDOFORIGINAL()) == 0)
|
194
|
+
{
|
195
|
+
$self->PushToGroup( NaturalDocs::Menu::Entry->New(::MENU_ENDOFORIGINAL(), undef, undef, undef) );
|
196
|
+
$self->SetFlags( $self->Flags() | ::MENU_GROUP_HASENDOFORIGINAL() );
|
197
|
+
};
|
198
|
+
};
|
199
|
+
|
200
|
+
|
201
|
+
1;
|
@@ -0,0 +1,76 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::NDMarkup
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A package of support functions for dealing with <NDMarkup>.
|
8
|
+
#
|
9
|
+
# Usage and Dependencies:
|
10
|
+
#
|
11
|
+
# The package doesn't depend on any Natural Docs packages and is ready to use right away.
|
12
|
+
#
|
13
|
+
###############################################################################
|
14
|
+
|
15
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
16
|
+
# Natural Docs is licensed under the GPL
|
17
|
+
|
18
|
+
|
19
|
+
use strict;
|
20
|
+
use integer;
|
21
|
+
|
22
|
+
package NaturalDocs::NDMarkup;
|
23
|
+
|
24
|
+
#
|
25
|
+
# Function: ConvertAmpChars
|
26
|
+
#
|
27
|
+
# Substitutes certain characters with their <NDMarkup> amp chars.
|
28
|
+
#
|
29
|
+
# Parameters:
|
30
|
+
#
|
31
|
+
# text - The block of text to convert.
|
32
|
+
#
|
33
|
+
# Returns:
|
34
|
+
#
|
35
|
+
# The converted text block.
|
36
|
+
#
|
37
|
+
sub ConvertAmpChars #(text)
|
38
|
+
{
|
39
|
+
my ($self, $text) = @_;
|
40
|
+
|
41
|
+
$text =~ s/&/&/g;
|
42
|
+
$text =~ s/</</g;
|
43
|
+
$text =~ s/>/>/g;
|
44
|
+
$text =~ s/\"/"/g;
|
45
|
+
|
46
|
+
return $text;
|
47
|
+
};
|
48
|
+
|
49
|
+
|
50
|
+
#
|
51
|
+
# Function: RestoreAmpChars
|
52
|
+
#
|
53
|
+
# Replaces <NDMarkup> amp chars with their original symbols.
|
54
|
+
#
|
55
|
+
# Parameters:
|
56
|
+
#
|
57
|
+
# text - The text to restore.
|
58
|
+
#
|
59
|
+
# Returns:
|
60
|
+
#
|
61
|
+
# The restored text.
|
62
|
+
#
|
63
|
+
sub RestoreAmpChars #(text)
|
64
|
+
{
|
65
|
+
my ($self, $text) = @_;
|
66
|
+
|
67
|
+
$text =~ s/"/\"/g;
|
68
|
+
$text =~ s/>/>/g;
|
69
|
+
$text =~ s/</</g;
|
70
|
+
$text =~ s/&/&/g;
|
71
|
+
|
72
|
+
return $text;
|
73
|
+
};
|
74
|
+
|
75
|
+
|
76
|
+
1;
|
@@ -0,0 +1,1331 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::Parser
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A package that coordinates source file parsing between the <NaturalDocs::Languages::Base>-derived objects and its own
|
8
|
+
# sub-packages such as <NaturalDocs::Parser::Native>. Also handles sending symbols to <NaturalDocs::SymbolTable> and
|
9
|
+
# other generic topic processing.
|
10
|
+
#
|
11
|
+
# Usage and Dependencies:
|
12
|
+
#
|
13
|
+
# - Prior to use, <NaturalDocs::Settings>, <NaturalDocs::Languages>, <NaturalDocs::Project>, <NaturalDocs::SymbolTable>,
|
14
|
+
# and <NaturalDocs::ClassHierarchy> must be initialized. <NaturalDocs::SymbolTable> and <NaturalDocs::ClassHierarchy>
|
15
|
+
# do not have to be fully resolved.
|
16
|
+
#
|
17
|
+
# - Aside from that, the package is ready to use right away. It does not have its own initialization function.
|
18
|
+
#
|
19
|
+
###############################################################################
|
20
|
+
|
21
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
22
|
+
# Natural Docs is licensed under the GPL
|
23
|
+
|
24
|
+
use NaturalDocs::Parser::ParsedTopic;
|
25
|
+
use NaturalDocs::Parser::Native;
|
26
|
+
use NaturalDocs::Parser::JavaDoc;
|
27
|
+
|
28
|
+
use strict;
|
29
|
+
use integer;
|
30
|
+
|
31
|
+
package NaturalDocs::Parser;
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
###############################################################################
|
36
|
+
# Group: Variables
|
37
|
+
|
38
|
+
|
39
|
+
#
|
40
|
+
# var: sourceFile
|
41
|
+
#
|
42
|
+
# The source <FileName> currently being parsed.
|
43
|
+
#
|
44
|
+
my $sourceFile;
|
45
|
+
|
46
|
+
#
|
47
|
+
# var: language
|
48
|
+
#
|
49
|
+
# The language object for the file, derived from <NaturalDocs::Languages::Base>.
|
50
|
+
#
|
51
|
+
my $language;
|
52
|
+
|
53
|
+
#
|
54
|
+
# Array: parsedFile
|
55
|
+
#
|
56
|
+
# An array of <NaturalDocs::Parser::ParsedTopic> objects.
|
57
|
+
#
|
58
|
+
my @parsedFile;
|
59
|
+
|
60
|
+
|
61
|
+
#
|
62
|
+
# bool: parsingForInformation
|
63
|
+
# Whether <ParseForInformation()> was called. If false, then <ParseForBuild()> was called.
|
64
|
+
#
|
65
|
+
my $parsingForInformation;
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
###############################################################################
|
70
|
+
# Group: Functions
|
71
|
+
|
72
|
+
#
|
73
|
+
# Function: ParseForInformation
|
74
|
+
#
|
75
|
+
# Parses the input file for information. Will update the information about the file in <NaturalDocs::SymbolTable> and
|
76
|
+
# <NaturalDocs::Project>.
|
77
|
+
#
|
78
|
+
# Parameters:
|
79
|
+
#
|
80
|
+
# file - The <FileName> to parse.
|
81
|
+
#
|
82
|
+
sub ParseForInformation #(file)
|
83
|
+
{
|
84
|
+
my ($self, $file) = @_;
|
85
|
+
$sourceFile = $file;
|
86
|
+
|
87
|
+
$parsingForInformation = 1;
|
88
|
+
|
89
|
+
# Watch this parse so we detect any changes.
|
90
|
+
NaturalDocs::SymbolTable->WatchFileForChanges($sourceFile);
|
91
|
+
NaturalDocs::ClassHierarchy->WatchFileForChanges($sourceFile);
|
92
|
+
NaturalDocs::SourceDB->WatchFileForChanges($sourceFile);
|
93
|
+
|
94
|
+
my $defaultMenuTitle = $self->Parse();
|
95
|
+
|
96
|
+
foreach my $topic (@parsedFile)
|
97
|
+
{
|
98
|
+
# Add a symbol for the topic.
|
99
|
+
|
100
|
+
my $type = $topic->Type();
|
101
|
+
if ($type eq ::TOPIC_ENUMERATION())
|
102
|
+
{ $type = ::TOPIC_TYPE(); };
|
103
|
+
|
104
|
+
NaturalDocs::SymbolTable->AddSymbol($topic->Symbol(), $sourceFile, $type,
|
105
|
+
$topic->Prototype(), $topic->Summary());
|
106
|
+
|
107
|
+
|
108
|
+
# You can't put the function call directly in a while with a regex. It has to sit in a variable to work.
|
109
|
+
my $body = $topic->Body();
|
110
|
+
|
111
|
+
|
112
|
+
# If it's a list or enum topic, add a symbol for each description list entry.
|
113
|
+
|
114
|
+
if ($topic->IsList() || $topic->Type() eq ::TOPIC_ENUMERATION())
|
115
|
+
{
|
116
|
+
# We'll hijack the enum constants to apply to non-enum behavior too.
|
117
|
+
my $behavior;
|
118
|
+
|
119
|
+
if ($topic->Type() eq ::TOPIC_ENUMERATION())
|
120
|
+
{
|
121
|
+
$type = ::TOPIC_CONSTANT();
|
122
|
+
$behavior = $language->EnumValues();
|
123
|
+
}
|
124
|
+
elsif (NaturalDocs::Topics->TypeInfo($topic->Type())->Scope() == ::SCOPE_ALWAYS_GLOBAL())
|
125
|
+
{
|
126
|
+
$behavior = ::ENUM_GLOBAL();
|
127
|
+
}
|
128
|
+
else
|
129
|
+
{
|
130
|
+
$behavior = ::ENUM_UNDER_PARENT();
|
131
|
+
};
|
132
|
+
|
133
|
+
while ($body =~ /<ds>([^<]+)<\/ds><dd>(.*?)<\/dd>/g)
|
134
|
+
{
|
135
|
+
my ($listTextSymbol, $listSummary) = ($1, $2);
|
136
|
+
|
137
|
+
$listTextSymbol = NaturalDocs::NDMarkup->RestoreAmpChars($listTextSymbol);
|
138
|
+
my $listSymbol = NaturalDocs::SymbolString->FromText($listTextSymbol);
|
139
|
+
|
140
|
+
if ($behavior == ::ENUM_UNDER_PARENT())
|
141
|
+
{ $listSymbol = NaturalDocs::SymbolString->Join($topic->Package(), $listSymbol); }
|
142
|
+
elsif ($behavior == ::ENUM_UNDER_TYPE())
|
143
|
+
{ $listSymbol = NaturalDocs::SymbolString->Join($topic->Symbol(), $listSymbol); };
|
144
|
+
|
145
|
+
NaturalDocs::SymbolTable->AddSymbol($listSymbol, $sourceFile, $type, undef,
|
146
|
+
$self->GetSummaryFromDescriptionList($listSummary));
|
147
|
+
};
|
148
|
+
};
|
149
|
+
|
150
|
+
|
151
|
+
# Add references in the topic.
|
152
|
+
|
153
|
+
while ($body =~ /<link target=\"([^\"]*)\" name=\"[^\"]*\" original=\"[^\"]*\">/g)
|
154
|
+
{
|
155
|
+
my $linkText = NaturalDocs::NDMarkup->RestoreAmpChars($1);
|
156
|
+
my $linkSymbol = NaturalDocs::SymbolString->FromText($linkText);
|
157
|
+
|
158
|
+
NaturalDocs::SymbolTable->AddReference(::REFERENCE_TEXT(), $linkSymbol,
|
159
|
+
$topic->Package(), $topic->Using(), $sourceFile);
|
160
|
+
};
|
161
|
+
|
162
|
+
|
163
|
+
# Add images in the topic.
|
164
|
+
|
165
|
+
while ($body =~ /<img mode=\"[^\"]*\" target=\"([^\"]+)\" original=\"[^\"]*\">/g)
|
166
|
+
{
|
167
|
+
my $target = NaturalDocs::NDMarkup->RestoreAmpChars($1);
|
168
|
+
NaturalDocs::ImageReferenceTable->AddReference($sourceFile, $target);
|
169
|
+
};
|
170
|
+
};
|
171
|
+
|
172
|
+
# Handle any changes to the file.
|
173
|
+
NaturalDocs::ClassHierarchy->AnalyzeChanges();
|
174
|
+
NaturalDocs::SymbolTable->AnalyzeChanges();
|
175
|
+
NaturalDocs::SourceDB->AnalyzeWatchedFileChanges();
|
176
|
+
|
177
|
+
# Update project on the file's characteristics.
|
178
|
+
my $hasContent = (scalar @parsedFile > 0);
|
179
|
+
|
180
|
+
NaturalDocs::Project->SetHasContent($sourceFile, $hasContent);
|
181
|
+
if ($hasContent)
|
182
|
+
{ NaturalDocs::Project->SetDefaultMenuTitle($sourceFile, $defaultMenuTitle); };
|
183
|
+
|
184
|
+
# We don't need to keep this around.
|
185
|
+
@parsedFile = ( );
|
186
|
+
};
|
187
|
+
|
188
|
+
|
189
|
+
#
|
190
|
+
# Function: ParseForBuild
|
191
|
+
#
|
192
|
+
# Parses the input file for building, returning it as a <NaturalDocs::Parser::ParsedTopic> arrayref.
|
193
|
+
#
|
194
|
+
# Note that all new and changed files should be parsed for symbols via <ParseForInformation()> before calling this function on
|
195
|
+
# *any* file. The reason is that <NaturalDocs::SymbolTable> needs to know about all the symbol definitions and references to
|
196
|
+
# resolve them properly.
|
197
|
+
#
|
198
|
+
# Parameters:
|
199
|
+
#
|
200
|
+
# file - The <FileName> to parse for building.
|
201
|
+
#
|
202
|
+
# Returns:
|
203
|
+
#
|
204
|
+
# An arrayref of the source file as <NaturalDocs::Parser::ParsedTopic> objects.
|
205
|
+
#
|
206
|
+
sub ParseForBuild #(file)
|
207
|
+
{
|
208
|
+
my ($self, $file) = @_;
|
209
|
+
$sourceFile = $file;
|
210
|
+
|
211
|
+
$parsingForInformation = undef;
|
212
|
+
|
213
|
+
$self->Parse();
|
214
|
+
|
215
|
+
return \@parsedFile;
|
216
|
+
};
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
###############################################################################
|
222
|
+
# Group: Interface Functions
|
223
|
+
|
224
|
+
|
225
|
+
#
|
226
|
+
# Function: OnComment
|
227
|
+
#
|
228
|
+
# The function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a comment
|
229
|
+
# suitable for documentation.
|
230
|
+
#
|
231
|
+
# Parameters:
|
232
|
+
#
|
233
|
+
# commentLines - An arrayref of the comment's lines. The language's comment symbols should be converted to spaces,
|
234
|
+
# and there should be no line break characters at the end of each line. *The original memory will be
|
235
|
+
# changed.*
|
236
|
+
# lineNumber - The line number of the first of the comment lines.
|
237
|
+
# isJavaDoc - Whether the comment is in JavaDoc format.
|
238
|
+
#
|
239
|
+
# Returns:
|
240
|
+
#
|
241
|
+
# The number of topics created by this comment, or zero if none.
|
242
|
+
#
|
243
|
+
sub OnComment #(string[] commentLines, int lineNumber, bool isJavaDoc)
|
244
|
+
{
|
245
|
+
my ($self, $commentLines, $lineNumber, $isJavaDoc) = @_;
|
246
|
+
|
247
|
+
$self->CleanComment($commentLines);
|
248
|
+
|
249
|
+
# We check if it's definitely Natural Docs content first. This overrides all else, since it's possible that a comment could start
|
250
|
+
# with a topic line yet have something that looks like a JavaDoc tag. Natural Docs wins in this case.
|
251
|
+
if (NaturalDocs::Parser::Native->IsMine($commentLines, $isJavaDoc))
|
252
|
+
{ return NaturalDocs::Parser::Native->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile); }
|
253
|
+
|
254
|
+
elsif (NaturalDocs::Parser::JavaDoc->IsMine($commentLines, $isJavaDoc))
|
255
|
+
{ return NaturalDocs::Parser::JavaDoc->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile); }
|
256
|
+
|
257
|
+
# If the content is ambiguous and it's a JavaDoc-styled comment, treat it as Natural Docs content.
|
258
|
+
elsif ($isJavaDoc)
|
259
|
+
{ return NaturalDocs::Parser::Native->ParseComment($commentLines, $isJavaDoc, $lineNumber, \@parsedFile); }
|
260
|
+
};
|
261
|
+
|
262
|
+
|
263
|
+
#
|
264
|
+
# Function: OnClass
|
265
|
+
#
|
266
|
+
# A function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a class declaration.
|
267
|
+
#
|
268
|
+
# Parameters:
|
269
|
+
#
|
270
|
+
# class - The <SymbolString> of the class encountered.
|
271
|
+
#
|
272
|
+
sub OnClass #(class)
|
273
|
+
{
|
274
|
+
my ($self, $class) = @_;
|
275
|
+
|
276
|
+
if ($parsingForInformation)
|
277
|
+
{ NaturalDocs::ClassHierarchy->AddClass($sourceFile, $class); };
|
278
|
+
};
|
279
|
+
|
280
|
+
|
281
|
+
#
|
282
|
+
# Function: OnClassParent
|
283
|
+
#
|
284
|
+
# A function called by <NaturalDocs::Languages::Base>-derived objects when their parsers encounter a declaration of
|
285
|
+
# inheritance.
|
286
|
+
#
|
287
|
+
# Parameters:
|
288
|
+
#
|
289
|
+
# class - The <SymbolString> of the class we're in.
|
290
|
+
# parent - The <SymbolString> of the class it inherits.
|
291
|
+
# scope - The package <SymbolString> that the reference appeared in.
|
292
|
+
# using - An arrayref of package <SymbolStrings> that the reference has access to via "using" statements.
|
293
|
+
# resolvingFlags - Any <Resolving Flags> to be used when resolving the reference. <RESOLVE_NOPLURAL> is added
|
294
|
+
# automatically since that would never apply to source code.
|
295
|
+
#
|
296
|
+
sub OnClassParent #(class, parent, scope, using, resolvingFlags)
|
297
|
+
{
|
298
|
+
my ($self, $class, $parent, $scope, $using, $resolvingFlags) = @_;
|
299
|
+
|
300
|
+
if ($parsingForInformation)
|
301
|
+
{
|
302
|
+
NaturalDocs::ClassHierarchy->AddParentReference($sourceFile, $class, $parent, $scope, $using,
|
303
|
+
$resolvingFlags | ::RESOLVE_NOPLURAL());
|
304
|
+
};
|
305
|
+
};
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
###############################################################################
|
310
|
+
# Group: Support Functions
|
311
|
+
|
312
|
+
|
313
|
+
# Function: Parse
|
314
|
+
#
|
315
|
+
# Opens the source file and parses process. Most of the actual parsing is done in <NaturalDocs::Languages::Base->ParseFile()>
|
316
|
+
# and <OnComment()>, though.
|
317
|
+
#
|
318
|
+
# *Do not call externally.* Rather, call <ParseForInformation()> or <ParseForBuild()>.
|
319
|
+
#
|
320
|
+
# Returns:
|
321
|
+
#
|
322
|
+
# The default menu title of the file. Will be the <FileName> if nothing better is found.
|
323
|
+
#
|
324
|
+
sub Parse
|
325
|
+
{
|
326
|
+
my ($self) = @_;
|
327
|
+
|
328
|
+
NaturalDocs::Error->OnStartParsing($sourceFile);
|
329
|
+
|
330
|
+
$language = NaturalDocs::Languages->LanguageOf($sourceFile);
|
331
|
+
NaturalDocs::Parser::Native->Start();
|
332
|
+
@parsedFile = ( );
|
333
|
+
|
334
|
+
my ($autoTopics, $scopeRecord) = $language->ParseFile($sourceFile, \@parsedFile);
|
335
|
+
|
336
|
+
|
337
|
+
$self->AddToClassHierarchy();
|
338
|
+
|
339
|
+
$self->BreakLists();
|
340
|
+
|
341
|
+
if (defined $autoTopics)
|
342
|
+
{
|
343
|
+
if (defined $scopeRecord)
|
344
|
+
{ $self->RepairPackages($autoTopics, $scopeRecord); };
|
345
|
+
|
346
|
+
$self->MergeAutoTopics($language, $autoTopics);
|
347
|
+
};
|
348
|
+
|
349
|
+
$self->RemoveRemainingHeaderlessTopics();
|
350
|
+
|
351
|
+
|
352
|
+
# We don't need to do this if there aren't any auto-topics because the only package changes would be implied by the comments.
|
353
|
+
if (defined $autoTopics)
|
354
|
+
{ $self->AddPackageDelineators(); };
|
355
|
+
|
356
|
+
if (!NaturalDocs::Settings->NoAutoGroup())
|
357
|
+
{ $self->MakeAutoGroups($autoTopics); };
|
358
|
+
|
359
|
+
|
360
|
+
# Set the menu title.
|
361
|
+
|
362
|
+
my $defaultMenuTitle = $sourceFile;
|
363
|
+
|
364
|
+
if (scalar @parsedFile)
|
365
|
+
{
|
366
|
+
my $addFileTitle;
|
367
|
+
|
368
|
+
if (NaturalDocs::Settings->OnlyFileTitles())
|
369
|
+
{
|
370
|
+
# We still want to use the title from the topics if the first one is a file.
|
371
|
+
if ($parsedFile[0]->Type() eq ::TOPIC_FILE())
|
372
|
+
{ $addFileTitle = 0; }
|
373
|
+
else
|
374
|
+
{ $addFileTitle = 1; };
|
375
|
+
}
|
376
|
+
elsif (scalar @parsedFile == 1 || NaturalDocs::Topics->TypeInfo( $parsedFile[0]->Type() )->PageTitleIfFirst())
|
377
|
+
{ $addFileTitle = 0; }
|
378
|
+
else
|
379
|
+
{ $addFileTitle = 1; };
|
380
|
+
|
381
|
+
if (!$addFileTitle)
|
382
|
+
{
|
383
|
+
$defaultMenuTitle = $parsedFile[0]->Title();
|
384
|
+
}
|
385
|
+
else
|
386
|
+
{
|
387
|
+
# If the title ended up being the file name, add a leading section for it.
|
388
|
+
|
389
|
+
unshift @parsedFile,
|
390
|
+
NaturalDocs::Parser::ParsedTopic->New(::TOPIC_FILE(), (NaturalDocs::File->SplitPath($sourceFile))[2],
|
391
|
+
undef, undef, undef, undef, undef, 1, undef);
|
392
|
+
};
|
393
|
+
};
|
394
|
+
|
395
|
+
NaturalDocs::Error->OnEndParsing($sourceFile);
|
396
|
+
|
397
|
+
return $defaultMenuTitle;
|
398
|
+
};
|
399
|
+
|
400
|
+
|
401
|
+
#
|
402
|
+
# Function: CleanComment
|
403
|
+
#
|
404
|
+
# Removes any extraneous formatting and whitespace from the comment. Eliminates comment boxes, horizontal lines, trailing
|
405
|
+
# whitespace from lines, and expands all tab characters. It keeps leading whitespace, though, since it may be needed for
|
406
|
+
# example code, and blank lines, since the original line numbers are needed.
|
407
|
+
#
|
408
|
+
# Parameters:
|
409
|
+
#
|
410
|
+
# commentLines - An arrayref of the comment lines to clean. *The original memory will be changed.* Lines should have the
|
411
|
+
# language's comment symbols replaced by spaces and not have a trailing line break.
|
412
|
+
#
|
413
|
+
sub CleanComment #(commentLines)
|
414
|
+
{
|
415
|
+
my ($self, $commentLines) = @_;
|
416
|
+
|
417
|
+
use constant DONT_KNOW => 0;
|
418
|
+
use constant IS_UNIFORM => 1;
|
419
|
+
use constant IS_UNIFORM_IF_AT_END => 2;
|
420
|
+
use constant IS_NOT_UNIFORM => 3;
|
421
|
+
|
422
|
+
my $leftSide = DONT_KNOW;
|
423
|
+
my $rightSide = DONT_KNOW;
|
424
|
+
my $leftSideChar;
|
425
|
+
my $rightSideChar;
|
426
|
+
|
427
|
+
my $index = 0;
|
428
|
+
my $tabLength = NaturalDocs::Settings->TabLength();
|
429
|
+
|
430
|
+
while ($index < scalar @$commentLines)
|
431
|
+
{
|
432
|
+
# Strip trailing whitespace from the original.
|
433
|
+
|
434
|
+
$commentLines->[$index] =~ s/[ \t]+$//;
|
435
|
+
|
436
|
+
|
437
|
+
# Expand tabs in the original. This method is almost six times faster than Text::Tabs' method.
|
438
|
+
|
439
|
+
my $tabIndex = index($commentLines->[$index], "\t");
|
440
|
+
|
441
|
+
while ($tabIndex != -1)
|
442
|
+
{
|
443
|
+
substr( $commentLines->[$index], $tabIndex, 1, ' ' x ($tabLength - ($tabIndex % $tabLength)) );
|
444
|
+
$tabIndex = index($commentLines->[$index], "\t", $tabIndex);
|
445
|
+
};
|
446
|
+
|
447
|
+
|
448
|
+
# Make a working copy and strip leading whitespace as well. This has to be done after tabs are expanded because
|
449
|
+
# stripping indentation could change how far tabs are expanded.
|
450
|
+
|
451
|
+
my $line = $commentLines->[$index];
|
452
|
+
$line =~ s/^ +//;
|
453
|
+
|
454
|
+
# If the line is blank...
|
455
|
+
if (!length $line)
|
456
|
+
{
|
457
|
+
# If we have a potential vertical line, this only acceptable if it's at the end of the comment.
|
458
|
+
if ($leftSide == IS_UNIFORM)
|
459
|
+
{ $leftSide = IS_UNIFORM_IF_AT_END; };
|
460
|
+
if ($rightSide == IS_UNIFORM)
|
461
|
+
{ $rightSide = IS_UNIFORM_IF_AT_END; };
|
462
|
+
}
|
463
|
+
|
464
|
+
# If there's at least four symbols in a row, it's a horizontal line. The second regex supports differing edge characters. It
|
465
|
+
# doesn't matter if any of this matches the left and right side symbols. The length < 256 is a sanity check, because that
|
466
|
+
# regexp has caused the perl regexp engine to choke on an insane line someone sent me from an automatically generated
|
467
|
+
# file. It had over 10k characters on the first line, and most of them were 0x00.
|
468
|
+
elsif ($line =~ /^([^a-zA-Z0-9 ])\1{3,}$/ ||
|
469
|
+
(length $line < 256 && $line =~ /^([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$/) )
|
470
|
+
{
|
471
|
+
# Ignore it. This has no effect on the vertical line detection. We want to keep it in the output though in case it was
|
472
|
+
# in a code section.
|
473
|
+
}
|
474
|
+
|
475
|
+
# If the line is not blank or a horizontal line...
|
476
|
+
else
|
477
|
+
{
|
478
|
+
# More content means any previous blank lines are no longer tolerated in vertical line detection. They are only
|
479
|
+
# acceptable at the end of the comment.
|
480
|
+
|
481
|
+
if ($leftSide == IS_UNIFORM_IF_AT_END)
|
482
|
+
{ $leftSide = IS_NOT_UNIFORM; };
|
483
|
+
if ($rightSide == IS_UNIFORM_IF_AT_END)
|
484
|
+
{ $rightSide = IS_NOT_UNIFORM; };
|
485
|
+
|
486
|
+
|
487
|
+
# Detect vertical lines. Lines are only lines if they are followed by whitespace or a connected horizontal line.
|
488
|
+
# Otherwise we may accidentally detect lines from short comments that just happen to have every first or last
|
489
|
+
# character the same.
|
490
|
+
|
491
|
+
if ($leftSide != IS_NOT_UNIFORM)
|
492
|
+
{
|
493
|
+
if ($line =~ /^([^a-zA-Z0-9])\1*(?: |$)/)
|
494
|
+
{
|
495
|
+
if ($leftSide == DONT_KNOW)
|
496
|
+
{
|
497
|
+
$leftSide = IS_UNIFORM;
|
498
|
+
$leftSideChar = $1;
|
499
|
+
}
|
500
|
+
else # ($leftSide == IS_UNIFORM) Other choices already ruled out.
|
501
|
+
{
|
502
|
+
if ($leftSideChar ne $1)
|
503
|
+
{ $leftSide = IS_NOT_UNIFORM; };
|
504
|
+
};
|
505
|
+
}
|
506
|
+
# We'll tolerate the lack of symbols on the left on the first line, because it may be a
|
507
|
+
# /* Function: Whatever
|
508
|
+
# * Description.
|
509
|
+
# */
|
510
|
+
# comment which would have the leading /* blanked out.
|
511
|
+
elsif ($index != 0)
|
512
|
+
{
|
513
|
+
$leftSide = IS_NOT_UNIFORM;
|
514
|
+
};
|
515
|
+
};
|
516
|
+
|
517
|
+
if ($rightSide != IS_NOT_UNIFORM)
|
518
|
+
{
|
519
|
+
if ($line =~ / ([^a-zA-Z0-9])\1*$/)
|
520
|
+
{
|
521
|
+
if ($rightSide == DONT_KNOW)
|
522
|
+
{
|
523
|
+
$rightSide = IS_UNIFORM;
|
524
|
+
$rightSideChar = $1;
|
525
|
+
}
|
526
|
+
else # ($rightSide == IS_UNIFORM) Other choices already ruled out.
|
527
|
+
{
|
528
|
+
if ($rightSideChar ne $1)
|
529
|
+
{ $rightSide = IS_NOT_UNIFORM; };
|
530
|
+
};
|
531
|
+
}
|
532
|
+
else
|
533
|
+
{
|
534
|
+
$rightSide = IS_NOT_UNIFORM;
|
535
|
+
};
|
536
|
+
};
|
537
|
+
|
538
|
+
# We'll remove vertical lines later if they're uniform throughout the entire comment.
|
539
|
+
};
|
540
|
+
|
541
|
+
$index++;
|
542
|
+
};
|
543
|
+
|
544
|
+
|
545
|
+
if ($leftSide == IS_UNIFORM_IF_AT_END)
|
546
|
+
{ $leftSide = IS_UNIFORM; };
|
547
|
+
if ($rightSide == IS_UNIFORM_IF_AT_END)
|
548
|
+
{ $rightSide = IS_UNIFORM; };
|
549
|
+
|
550
|
+
|
551
|
+
$index = 0;
|
552
|
+
my $inCodeSection = 0;
|
553
|
+
|
554
|
+
while ($index < scalar @$commentLines)
|
555
|
+
{
|
556
|
+
# Clear horizontal lines only if we're not in a code section.
|
557
|
+
if ($commentLines->[$index] =~ /^ *([^a-zA-Z0-9 ])\1{3,}$/ ||
|
558
|
+
( length $commentLines->[$index] < 256 &&
|
559
|
+
$commentLines->[$index] =~ /^ *([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$/ ) )
|
560
|
+
{
|
561
|
+
if (!$inCodeSection)
|
562
|
+
{ $commentLines->[$index] = ''; }
|
563
|
+
}
|
564
|
+
|
565
|
+
else
|
566
|
+
{
|
567
|
+
# Clear vertical lines.
|
568
|
+
|
569
|
+
if ($leftSide == IS_UNIFORM)
|
570
|
+
{
|
571
|
+
# This works because every line should either start this way, be blank, or be the first line that doesn't start with a
|
572
|
+
# symbol.
|
573
|
+
$commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1*//;
|
574
|
+
};
|
575
|
+
|
576
|
+
if ($rightSide == IS_UNIFORM)
|
577
|
+
{
|
578
|
+
$commentLines->[$index] =~ s/ *([^a-zA-Z0-9 ])\1*$//;
|
579
|
+
};
|
580
|
+
|
581
|
+
|
582
|
+
# Clear horizontal lines again if there were vertical lines. This catches lines that were separated from the verticals by
|
583
|
+
# whitespace.
|
584
|
+
|
585
|
+
if (($leftSide == IS_UNIFORM || $rightSide == IS_UNIFORM) && !$inCodeSection)
|
586
|
+
{
|
587
|
+
$commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1{3,}$//;
|
588
|
+
$commentLines->[$index] =~ s/^ *([^a-zA-Z0-9 ])\1*([^a-zA-Z0-9 ])\2{3,}([^a-zA-Z0-9 ])\3*$//;
|
589
|
+
};
|
590
|
+
|
591
|
+
|
592
|
+
# Check for the start and end of code sections. Note that this doesn't affect vertical line removal.
|
593
|
+
|
594
|
+
if (!$inCodeSection &&
|
595
|
+
$commentLines->[$index] =~ /^ *\( *(?:(?:start|begin)? +)?(?:table|code|example|diagram) *\)$/i )
|
596
|
+
{
|
597
|
+
$inCodeSection = 1;
|
598
|
+
}
|
599
|
+
elsif ($inCodeSection &&
|
600
|
+
$commentLines->[$index] =~ /^ *\( *(?:end|finish|done)(?: +(?:table|code|example|diagram))? *\)$/i)
|
601
|
+
{
|
602
|
+
$inCodeSection = 0;
|
603
|
+
}
|
604
|
+
}
|
605
|
+
|
606
|
+
|
607
|
+
$index++;
|
608
|
+
};
|
609
|
+
|
610
|
+
};
|
611
|
+
|
612
|
+
|
613
|
+
|
614
|
+
###############################################################################
|
615
|
+
# Group: Processing Functions
|
616
|
+
|
617
|
+
|
618
|
+
#
|
619
|
+
# Function: RepairPackages
|
620
|
+
#
|
621
|
+
# Recalculates the packages for all comment topics using the auto-topics and the scope record. Call this *before* calling
|
622
|
+
# <MergeAutoTopics()>.
|
623
|
+
#
|
624
|
+
# Parameters:
|
625
|
+
#
|
626
|
+
# autoTopics - A reference to the list of automatically generated <NaturalDocs::Parser::ParsedTopics>.
|
627
|
+
# scopeRecord - A reference to an array of <NaturalDocs::Languages::Advanced::ScopeChanges>.
|
628
|
+
#
|
629
|
+
sub RepairPackages #(autoTopics, scopeRecord)
|
630
|
+
{
|
631
|
+
my ($self, $autoTopics, $scopeRecord) = @_;
|
632
|
+
|
633
|
+
my $topicIndex = 0;
|
634
|
+
my $autoTopicIndex = 0;
|
635
|
+
my $scopeIndex = 0;
|
636
|
+
|
637
|
+
my $topic = $parsedFile[0];
|
638
|
+
my $autoTopic = $autoTopics->[0];
|
639
|
+
my $scopeChange = $scopeRecord->[0];
|
640
|
+
|
641
|
+
my $currentPackage;
|
642
|
+
my $inFakePackage;
|
643
|
+
|
644
|
+
while (defined $topic)
|
645
|
+
{
|
646
|
+
# First update the scope via the record if its defined and has the lowest line number.
|
647
|
+
if (defined $scopeChange &&
|
648
|
+
$scopeChange->LineNumber() <= $topic->LineNumber() &&
|
649
|
+
(!defined $autoTopic || $scopeChange->LineNumber() <= $autoTopic->LineNumber()) )
|
650
|
+
{
|
651
|
+
$currentPackage = $scopeChange->Scope();
|
652
|
+
$scopeIndex++;
|
653
|
+
$scopeChange = $scopeRecord->[$scopeIndex]; # Will be undef when past end.
|
654
|
+
$inFakePackage = undef;
|
655
|
+
}
|
656
|
+
|
657
|
+
# Next try to end a fake scope with an auto topic if its defined and has the lowest line number.
|
658
|
+
elsif (defined $autoTopic &&
|
659
|
+
$autoTopic->LineNumber() <= $topic->LineNumber())
|
660
|
+
{
|
661
|
+
if ($inFakePackage)
|
662
|
+
{
|
663
|
+
$currentPackage = $autoTopic->Package();
|
664
|
+
$inFakePackage = undef;
|
665
|
+
};
|
666
|
+
|
667
|
+
$autoTopicIndex++;
|
668
|
+
$autoTopic = $autoTopics->[$autoTopicIndex]; # Will be undef when past end.
|
669
|
+
}
|
670
|
+
|
671
|
+
|
672
|
+
# Finally try to handle the topic, since it has the lowest line number. Check for Type() because headerless topics won't have
|
673
|
+
# one.
|
674
|
+
else
|
675
|
+
{
|
676
|
+
my $scope;
|
677
|
+
if ($topic->Type())
|
678
|
+
{ $scope = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope(); }
|
679
|
+
else
|
680
|
+
{ $scope = ::SCOPE_NORMAL(); };
|
681
|
+
|
682
|
+
if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
683
|
+
{
|
684
|
+
# They should already have the correct class and scope.
|
685
|
+
$currentPackage = $topic->Package();
|
686
|
+
$inFakePackage = 1;
|
687
|
+
}
|
688
|
+
else
|
689
|
+
{
|
690
|
+
# Fix the package of everything else.
|
691
|
+
|
692
|
+
# Note that the first function or variable topic to appear in a fake package will assume that package even if it turns out
|
693
|
+
# to be incorrect in the actual code, since the topic will come before the auto-topic. This will be corrected in
|
694
|
+
# MergeAutoTopics().
|
695
|
+
|
696
|
+
$topic->SetPackage($currentPackage);
|
697
|
+
};
|
698
|
+
|
699
|
+
$topicIndex++;
|
700
|
+
$topic = $parsedFile[$topicIndex]; # Will be undef when past end.
|
701
|
+
};
|
702
|
+
};
|
703
|
+
|
704
|
+
};
|
705
|
+
|
706
|
+
|
707
|
+
#
|
708
|
+
# Function: MergeAutoTopics
|
709
|
+
#
|
710
|
+
# Merges the automatically generated topics into the file. If an auto-topic matches an existing topic, it will have it's prototype
|
711
|
+
# and package transferred. If it doesn't, the auto-topic will be inserted into the list unless
|
712
|
+
# <NaturalDocs::Settings->DocumentedOnly()> is set. If an existing topic doesn't have a title, it's assumed to be a headerless
|
713
|
+
# comment and will be merged with the next auto-topic or discarded.
|
714
|
+
#
|
715
|
+
# Parameters:
|
716
|
+
#
|
717
|
+
# language - The <NaturalDocs::Languages::Base>-derived class for the file.
|
718
|
+
# autoTopics - A reference to the list of automatically generated topics.
|
719
|
+
#
|
720
|
+
sub MergeAutoTopics #(language, autoTopics)
|
721
|
+
{
|
722
|
+
my ($self, $language, $autoTopics) = @_;
|
723
|
+
|
724
|
+
my $topicIndex = 0;
|
725
|
+
my $autoTopicIndex = 0;
|
726
|
+
|
727
|
+
# Keys are topic types, values are existence hashrefs of titles.
|
728
|
+
my %topicsInLists;
|
729
|
+
|
730
|
+
while ($topicIndex < scalar @parsedFile && $autoTopicIndex < scalar @$autoTopics)
|
731
|
+
{
|
732
|
+
my $topic = $parsedFile[$topicIndex];
|
733
|
+
my $autoTopic = $autoTopics->[$autoTopicIndex];
|
734
|
+
|
735
|
+
my $cleanTitle = $topic->Title();
|
736
|
+
$cleanTitle =~ s/[\t ]*\([^\(]*$//;
|
737
|
+
|
738
|
+
# Add the auto-topic if it's higher in the file than the current topic.
|
739
|
+
if ($autoTopic->LineNumber() < $topic->LineNumber())
|
740
|
+
{
|
741
|
+
if (exists $topicsInLists{$autoTopic->Type()} &&
|
742
|
+
exists $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()})
|
743
|
+
{
|
744
|
+
# Remove it from the list so a second one with the same name will be added.
|
745
|
+
delete $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()};
|
746
|
+
}
|
747
|
+
elsif (!NaturalDocs::Settings->DocumentedOnly())
|
748
|
+
{
|
749
|
+
splice(@parsedFile, $topicIndex, 0, $autoTopic);
|
750
|
+
$topicIndex++;
|
751
|
+
};
|
752
|
+
|
753
|
+
$autoTopicIndex++;
|
754
|
+
}
|
755
|
+
|
756
|
+
# Remove a headerless topic if there's another topic between it and the next auto-topic.
|
757
|
+
elsif (!$topic->Title() && $topicIndex + 1 < scalar @parsedFile &&
|
758
|
+
$parsedFile[$topicIndex+1]->LineNumber() < $autoTopic->LineNumber())
|
759
|
+
{
|
760
|
+
splice(@parsedFile, $topicIndex, 1);
|
761
|
+
}
|
762
|
+
|
763
|
+
# Transfer information if we have a match or a headerless topic.
|
764
|
+
elsif ( !$topic->Title() || ($topic->Type() == $autoTopic->Type() && index($autoTopic->Title(), $cleanTitle) != -1) )
|
765
|
+
{
|
766
|
+
$topic->SetType($autoTopic->Type());
|
767
|
+
$topic->SetPrototype($autoTopic->Prototype());
|
768
|
+
$topic->SetUsing($autoTopic->Using());
|
769
|
+
|
770
|
+
if (!$topic->Title())
|
771
|
+
{ $topic->SetTitle($autoTopic->Title()); };
|
772
|
+
|
773
|
+
if (NaturalDocs::Topics->TypeInfo($topic->Type())->Scope() != ::SCOPE_START())
|
774
|
+
{ $topic->SetPackage($autoTopic->Package()); }
|
775
|
+
elsif ($autoTopic->Package() ne $topic->Package())
|
776
|
+
{
|
777
|
+
my @autoPackageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($autoTopic->Package());
|
778
|
+
my @packageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($topic->Package());
|
779
|
+
|
780
|
+
while (scalar @autoPackageIdentifiers && $autoPackageIdentifiers[-1] eq $packageIdentifiers[-1])
|
781
|
+
{
|
782
|
+
pop @autoPackageIdentifiers;
|
783
|
+
pop @packageIdentifiers;
|
784
|
+
};
|
785
|
+
|
786
|
+
if (scalar @autoPackageIdentifiers)
|
787
|
+
{ $topic->SetPackage( NaturalDocs::SymbolString->Join(@autoPackageIdentifiers) ); };
|
788
|
+
};
|
789
|
+
|
790
|
+
$topicIndex++;
|
791
|
+
$autoTopicIndex++;
|
792
|
+
}
|
793
|
+
|
794
|
+
# Extract topics in lists.
|
795
|
+
elsif ($topic->IsList())
|
796
|
+
{
|
797
|
+
if (!exists $topicsInLists{$topic->Type()})
|
798
|
+
{ $topicsInLists{$topic->Type()} = { }; };
|
799
|
+
|
800
|
+
my $body = $topic->Body();
|
801
|
+
|
802
|
+
while ($body =~ /<ds>([^<]+)<\/ds>/g)
|
803
|
+
{ $topicsInLists{$topic->Type()}->{NaturalDocs::NDMarkup->RestoreAmpChars($1)} = 1; };
|
804
|
+
|
805
|
+
$topicIndex++;
|
806
|
+
}
|
807
|
+
|
808
|
+
# Otherwise there's no match. Skip the topic. The auto-topic will be added later.
|
809
|
+
else
|
810
|
+
{
|
811
|
+
$topicIndex++;
|
812
|
+
}
|
813
|
+
};
|
814
|
+
|
815
|
+
# Add any auto-topics remaining.
|
816
|
+
if (!NaturalDocs::Settings->DocumentedOnly())
|
817
|
+
{
|
818
|
+
while ($autoTopicIndex < scalar @$autoTopics)
|
819
|
+
{
|
820
|
+
my $autoTopic = $autoTopics->[$autoTopicIndex];
|
821
|
+
|
822
|
+
if (exists $topicsInLists{$autoTopic->Type()} &&
|
823
|
+
exists $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()})
|
824
|
+
{
|
825
|
+
# Remove it from the list so a second one with the same name will be added.
|
826
|
+
delete $topicsInLists{$autoTopic->Type()}->{$autoTopic->Title()};
|
827
|
+
}
|
828
|
+
else
|
829
|
+
{
|
830
|
+
push(@parsedFile, $autoTopic);
|
831
|
+
};
|
832
|
+
|
833
|
+
$autoTopicIndex++;
|
834
|
+
};
|
835
|
+
};
|
836
|
+
};
|
837
|
+
|
838
|
+
|
839
|
+
#
|
840
|
+
# Function: RemoveRemainingHeaderlessTopics
|
841
|
+
#
|
842
|
+
# After <MergeAutoTopics()> is done, this function removes any remaining headerless topics from the file. If they don't merge
|
843
|
+
# into anything, they're not valid topics.
|
844
|
+
#
|
845
|
+
sub RemoveRemainingHeaderlessTopics
|
846
|
+
{
|
847
|
+
my ($self) = @_;
|
848
|
+
|
849
|
+
my $index = 0;
|
850
|
+
while ($index < scalar @parsedFile)
|
851
|
+
{
|
852
|
+
if ($parsedFile[$index]->Title())
|
853
|
+
{ $index++; }
|
854
|
+
else
|
855
|
+
{ splice(@parsedFile, $index, 1); };
|
856
|
+
};
|
857
|
+
};
|
858
|
+
|
859
|
+
|
860
|
+
#
|
861
|
+
# Function: MakeAutoGroups
|
862
|
+
#
|
863
|
+
# Creates group topics for files that do not have them.
|
864
|
+
#
|
865
|
+
sub MakeAutoGroups
|
866
|
+
{
|
867
|
+
my ($self) = @_;
|
868
|
+
|
869
|
+
# No groups only one topic.
|
870
|
+
if (scalar @parsedFile < 2)
|
871
|
+
{ return; };
|
872
|
+
|
873
|
+
my $index = 0;
|
874
|
+
my $startStretch = 0;
|
875
|
+
|
876
|
+
# Skip the first entry if its the page title.
|
877
|
+
if (NaturalDocs::Topics->TypeInfo( $parsedFile[0]->Type() )->PageTitleIfFirst())
|
878
|
+
{
|
879
|
+
$index = 1;
|
880
|
+
$startStretch = 1;
|
881
|
+
};
|
882
|
+
|
883
|
+
# Make auto-groups for each stretch between scope-altering topics.
|
884
|
+
while ($index < scalar @parsedFile)
|
885
|
+
{
|
886
|
+
my $scope = NaturalDocs::Topics->TypeInfo($parsedFile[$index]->Type())->Scope();
|
887
|
+
|
888
|
+
if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
889
|
+
{
|
890
|
+
if ($index > $startStretch)
|
891
|
+
{ $index += $self->MakeAutoGroupsFor($startStretch, $index); };
|
892
|
+
|
893
|
+
$startStretch = $index + 1;
|
894
|
+
};
|
895
|
+
|
896
|
+
$index++;
|
897
|
+
};
|
898
|
+
|
899
|
+
if ($index > $startStretch)
|
900
|
+
{ $self->MakeAutoGroupsFor($startStretch, $index); };
|
901
|
+
};
|
902
|
+
|
903
|
+
|
904
|
+
#
|
905
|
+
# Function: MakeAutoGroupsFor
|
906
|
+
#
|
907
|
+
# Creates group topics for sections of files that do not have them. A support function for <MakeAutoGroups()>.
|
908
|
+
#
|
909
|
+
# Parameters:
|
910
|
+
#
|
911
|
+
# startIndex - The index to start at.
|
912
|
+
# endIndex - The index to end at. Not inclusive.
|
913
|
+
#
|
914
|
+
# Returns:
|
915
|
+
#
|
916
|
+
# The number of group topics added.
|
917
|
+
#
|
918
|
+
sub MakeAutoGroupsFor #(startIndex, endIndex)
|
919
|
+
{
|
920
|
+
my ($self, $startIndex, $endIndex) = @_;
|
921
|
+
|
922
|
+
# No groups if any are defined already.
|
923
|
+
for (my $i = $startIndex; $i < $endIndex; $i++)
|
924
|
+
{
|
925
|
+
if ($parsedFile[$i]->Type() eq ::TOPIC_GROUP())
|
926
|
+
{ return 0; };
|
927
|
+
};
|
928
|
+
|
929
|
+
|
930
|
+
use constant COUNT => 0;
|
931
|
+
use constant TYPE => 1;
|
932
|
+
use constant SECOND_TYPE => 2;
|
933
|
+
use constant SIZE => 3;
|
934
|
+
|
935
|
+
# This is an array of ( count, type, secondType ) triples. Count and Type will always be filled in; count is the number of
|
936
|
+
# consecutive topics of type. On the second pass, if small groups are combined secondType will be filled in. There will not be
|
937
|
+
# more than two types per group.
|
938
|
+
my @groups;
|
939
|
+
my $groupIndex = 0;
|
940
|
+
|
941
|
+
|
942
|
+
# First pass: Determine all the groups.
|
943
|
+
|
944
|
+
my $i = $startIndex;
|
945
|
+
my $currentType;
|
946
|
+
|
947
|
+
while ($i < $endIndex)
|
948
|
+
{
|
949
|
+
if (!defined $currentType || ($parsedFile[$i]->Type() ne $currentType && $parsedFile[$i]->Type() ne ::TOPIC_GENERIC()) )
|
950
|
+
{
|
951
|
+
if (defined $currentType)
|
952
|
+
{ $groupIndex += SIZE; };
|
953
|
+
|
954
|
+
$currentType = $parsedFile[$i]->Type();
|
955
|
+
|
956
|
+
$groups[$groupIndex + COUNT] = 1;
|
957
|
+
$groups[$groupIndex + TYPE] = $currentType;
|
958
|
+
}
|
959
|
+
else
|
960
|
+
{ $groups[$groupIndex + COUNT]++; };
|
961
|
+
|
962
|
+
$i++;
|
963
|
+
};
|
964
|
+
|
965
|
+
|
966
|
+
# Second pass: Combine groups based on "noise". Noise means types go from A to B to A at least once, and there are at least
|
967
|
+
# two groups in a row with three or less, and at least one of those groups is two or less. So 3, 3, 3 doesn't count as noise, but
|
968
|
+
# 3, 2, 3 does.
|
969
|
+
|
970
|
+
$groupIndex = 0;
|
971
|
+
|
972
|
+
# While there are at least three groups left...
|
973
|
+
while ($groupIndex < scalar @groups - (2 * SIZE))
|
974
|
+
{
|
975
|
+
# If the group two places in front of this one has the same type...
|
976
|
+
if ($groups[$groupIndex + (2 * SIZE) + TYPE] eq $groups[$groupIndex + TYPE])
|
977
|
+
{
|
978
|
+
# It means we went from A to B to A, which partially qualifies as noise.
|
979
|
+
|
980
|
+
my $firstType = $groups[$groupIndex + TYPE];
|
981
|
+
my $secondType = $groups[$groupIndex + SIZE + TYPE];
|
982
|
+
|
983
|
+
if (NaturalDocs::Topics->TypeInfo($firstType)->CanGroupWith($secondType) ||
|
984
|
+
NaturalDocs::Topics->TypeInfo($secondType)->CanGroupWith($firstType))
|
985
|
+
{
|
986
|
+
my $hasNoise;
|
987
|
+
|
988
|
+
my $hasThrees;
|
989
|
+
my $hasTwosOrOnes;
|
990
|
+
|
991
|
+
my $endIndex = $groupIndex;
|
992
|
+
|
993
|
+
while ($endIndex < scalar @groups &&
|
994
|
+
($groups[$endIndex + TYPE] eq $firstType || $groups[$endIndex + TYPE] eq $secondType))
|
995
|
+
{
|
996
|
+
if ($groups[$endIndex + COUNT] > 3)
|
997
|
+
{
|
998
|
+
# They must be consecutive to count.
|
999
|
+
$hasThrees = 0;
|
1000
|
+
$hasTwosOrOnes = 0;
|
1001
|
+
}
|
1002
|
+
elsif ($groups[$endIndex + COUNT] == 3)
|
1003
|
+
{
|
1004
|
+
$hasThrees = 1;
|
1005
|
+
|
1006
|
+
if ($hasTwosOrOnes)
|
1007
|
+
{ $hasNoise = 1; };
|
1008
|
+
}
|
1009
|
+
else # < 3
|
1010
|
+
{
|
1011
|
+
if ($hasThrees || $hasTwosOrOnes)
|
1012
|
+
{ $hasNoise = 1; };
|
1013
|
+
|
1014
|
+
$hasTwosOrOnes = 1;
|
1015
|
+
};
|
1016
|
+
|
1017
|
+
$endIndex += SIZE;
|
1018
|
+
};
|
1019
|
+
|
1020
|
+
if (!$hasNoise)
|
1021
|
+
{
|
1022
|
+
$groupIndex = $endIndex - SIZE;
|
1023
|
+
}
|
1024
|
+
else # hasNoise
|
1025
|
+
{
|
1026
|
+
$groups[$groupIndex + SECOND_TYPE] = $secondType;
|
1027
|
+
|
1028
|
+
for (my $noiseIndex = $groupIndex + SIZE; $noiseIndex < $endIndex; $noiseIndex += SIZE)
|
1029
|
+
{
|
1030
|
+
$groups[$groupIndex + COUNT] += $groups[$noiseIndex + COUNT];
|
1031
|
+
};
|
1032
|
+
|
1033
|
+
splice(@groups, $groupIndex + SIZE, $endIndex - $groupIndex - SIZE);
|
1034
|
+
|
1035
|
+
$groupIndex += SIZE;
|
1036
|
+
};
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
else # They can't group together
|
1040
|
+
{
|
1041
|
+
$groupIndex += SIZE;
|
1042
|
+
};
|
1043
|
+
}
|
1044
|
+
|
1045
|
+
else
|
1046
|
+
{ $groupIndex += SIZE; };
|
1047
|
+
};
|
1048
|
+
|
1049
|
+
|
1050
|
+
# Finally, create group topics for the parsed file.
|
1051
|
+
|
1052
|
+
$groupIndex = 0;
|
1053
|
+
$i = $startIndex;
|
1054
|
+
|
1055
|
+
while ($groupIndex < scalar @groups)
|
1056
|
+
{
|
1057
|
+
if ($groups[$groupIndex + TYPE] ne ::TOPIC_GENERIC())
|
1058
|
+
{
|
1059
|
+
my $topic = $parsedFile[$i];
|
1060
|
+
my $title = NaturalDocs::Topics->NameOfType($groups[$groupIndex + TYPE], 1);
|
1061
|
+
|
1062
|
+
if (defined $groups[$groupIndex + SECOND_TYPE])
|
1063
|
+
{ $title .= ' and ' . NaturalDocs::Topics->NameOfType($groups[$groupIndex + SECOND_TYPE], 1); };
|
1064
|
+
|
1065
|
+
splice(@parsedFile, $i, 0, NaturalDocs::Parser::ParsedTopic->New(::TOPIC_GROUP(),
|
1066
|
+
$title,
|
1067
|
+
$topic->Package(), $topic->Using(),
|
1068
|
+
undef, undef, undef,
|
1069
|
+
$topic->LineNumber()) );
|
1070
|
+
$i++;
|
1071
|
+
};
|
1072
|
+
|
1073
|
+
$i += $groups[$groupIndex + COUNT];
|
1074
|
+
$groupIndex += SIZE;
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
return (scalar @groups / SIZE);
|
1078
|
+
};
|
1079
|
+
|
1080
|
+
|
1081
|
+
#
|
1082
|
+
# Function: AddToClassHierarchy
|
1083
|
+
#
|
1084
|
+
# Adds any class topics to the class hierarchy, since they may not have been called with <OnClass()> if they didn't match up to
|
1085
|
+
# an auto-topic.
|
1086
|
+
#
|
1087
|
+
sub AddToClassHierarchy
|
1088
|
+
{
|
1089
|
+
my ($self) = @_;
|
1090
|
+
|
1091
|
+
foreach my $topic (@parsedFile)
|
1092
|
+
{
|
1093
|
+
if ($topic->Type() && NaturalDocs::Topics->TypeInfo( $topic->Type() )->ClassHierarchy())
|
1094
|
+
{
|
1095
|
+
if ($topic->IsList())
|
1096
|
+
{
|
1097
|
+
my $body = $topic->Body();
|
1098
|
+
|
1099
|
+
while ($body =~ /<ds>([^<]+)<\/ds>/g)
|
1100
|
+
{
|
1101
|
+
$self->OnClass( NaturalDocs::SymbolString->FromText( NaturalDocs::NDMarkup->RestoreAmpChars($1) ) );
|
1102
|
+
};
|
1103
|
+
}
|
1104
|
+
else
|
1105
|
+
{
|
1106
|
+
$self->OnClass($topic->Package());
|
1107
|
+
};
|
1108
|
+
};
|
1109
|
+
};
|
1110
|
+
};
|
1111
|
+
|
1112
|
+
|
1113
|
+
#
|
1114
|
+
# Function: AddPackageDelineators
|
1115
|
+
#
|
1116
|
+
# Adds section and class topics to make sure the package is correctly represented in the documentation. Should be called last in
|
1117
|
+
# this process.
|
1118
|
+
#
|
1119
|
+
sub AddPackageDelineators
|
1120
|
+
{
|
1121
|
+
my ($self) = @_;
|
1122
|
+
|
1123
|
+
my $index = 0;
|
1124
|
+
my $currentPackage;
|
1125
|
+
|
1126
|
+
# Values are the arrayref [ title, type ];
|
1127
|
+
my %usedPackages;
|
1128
|
+
|
1129
|
+
while ($index < scalar @parsedFile)
|
1130
|
+
{
|
1131
|
+
my $topic = $parsedFile[$index];
|
1132
|
+
|
1133
|
+
if ($topic->Package() ne $currentPackage)
|
1134
|
+
{
|
1135
|
+
$currentPackage = $topic->Package();
|
1136
|
+
my $scopeType = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope();
|
1137
|
+
|
1138
|
+
if ($scopeType == ::SCOPE_START())
|
1139
|
+
{
|
1140
|
+
$usedPackages{$currentPackage} = [ $topic->Title(), $topic->Type() ];
|
1141
|
+
}
|
1142
|
+
elsif ($scopeType == ::SCOPE_END())
|
1143
|
+
{
|
1144
|
+
my $newTopic;
|
1145
|
+
|
1146
|
+
if (!defined $currentPackage)
|
1147
|
+
{
|
1148
|
+
$newTopic = NaturalDocs::Parser::ParsedTopic->New(::TOPIC_SECTION(), 'Global',
|
1149
|
+
undef, undef,
|
1150
|
+
undef, undef, undef,
|
1151
|
+
$topic->LineNumber(), undef);
|
1152
|
+
}
|
1153
|
+
else
|
1154
|
+
{
|
1155
|
+
my ($title, $body, $summary, $type);
|
1156
|
+
my @packageIdentifiers = NaturalDocs::SymbolString->IdentifiersOf($currentPackage);
|
1157
|
+
|
1158
|
+
if (exists $usedPackages{$currentPackage})
|
1159
|
+
{
|
1160
|
+
$title = $usedPackages{$currentPackage}->[0];
|
1161
|
+
$type = $usedPackages{$currentPackage}->[1];
|
1162
|
+
$body = '<p>(continued)</p>';
|
1163
|
+
$summary = '(continued)';
|
1164
|
+
}
|
1165
|
+
else
|
1166
|
+
{
|
1167
|
+
$title = join($language->PackageSeparator(), @packageIdentifiers);
|
1168
|
+
$type = ::TOPIC_CLASS();
|
1169
|
+
|
1170
|
+
# Body and summary stay undef.
|
1171
|
+
|
1172
|
+
$usedPackages{$currentPackage} = $title;
|
1173
|
+
};
|
1174
|
+
|
1175
|
+
my @titleIdentifiers = NaturalDocs::SymbolString->IdentifiersOf( NaturalDocs::SymbolString->FromText($title) );
|
1176
|
+
for (my $i = 0; $i < scalar @titleIdentifiers; $i++)
|
1177
|
+
{ pop @packageIdentifiers; };
|
1178
|
+
|
1179
|
+
$newTopic = NaturalDocs::Parser::ParsedTopic->New($type, $title,
|
1180
|
+
NaturalDocs::SymbolString->Join(@packageIdentifiers), undef,
|
1181
|
+
undef, $summary, $body,
|
1182
|
+
$topic->LineNumber(), undef);
|
1183
|
+
}
|
1184
|
+
|
1185
|
+
splice(@parsedFile, $index, 0, $newTopic);
|
1186
|
+
$index++;
|
1187
|
+
}
|
1188
|
+
};
|
1189
|
+
|
1190
|
+
$index++;
|
1191
|
+
};
|
1192
|
+
};
|
1193
|
+
|
1194
|
+
|
1195
|
+
#
|
1196
|
+
# Function: BreakLists
|
1197
|
+
#
|
1198
|
+
# Breaks list topics into individual topics.
|
1199
|
+
#
|
1200
|
+
sub BreakLists
|
1201
|
+
{
|
1202
|
+
my $self = shift;
|
1203
|
+
|
1204
|
+
my $index = 0;
|
1205
|
+
|
1206
|
+
while ($index < scalar @parsedFile)
|
1207
|
+
{
|
1208
|
+
my $topic = $parsedFile[$index];
|
1209
|
+
|
1210
|
+
if ($topic->IsList() && NaturalDocs::Topics->TypeInfo( $topic->Type() )->BreakLists())
|
1211
|
+
{
|
1212
|
+
my $body = $topic->Body();
|
1213
|
+
|
1214
|
+
my @newTopics;
|
1215
|
+
my $newBody;
|
1216
|
+
|
1217
|
+
my $bodyIndex = 0;
|
1218
|
+
|
1219
|
+
for (;;)
|
1220
|
+
{
|
1221
|
+
my $startList = index($body, '<dl>', $bodyIndex);
|
1222
|
+
|
1223
|
+
if ($startList == -1)
|
1224
|
+
{ last; };
|
1225
|
+
|
1226
|
+
$newBody .= substr($body, $bodyIndex, $startList - $bodyIndex);
|
1227
|
+
|
1228
|
+
my $endList = index($body, '</dl>', $startList);
|
1229
|
+
my $listBody = substr($body, $startList, $endList - $startList);
|
1230
|
+
|
1231
|
+
while ($listBody =~ /<ds>([^<]+)<\/ds><dd>(.*?)<\/dd>/g)
|
1232
|
+
{
|
1233
|
+
my ($symbol, $description) = ($1, $2);
|
1234
|
+
|
1235
|
+
push @newTopics, NaturalDocs::Parser::ParsedTopic->New( $topic->Type(), $symbol, $topic->Package(),
|
1236
|
+
$topic->Using(), undef,
|
1237
|
+
$self->GetSummaryFromDescriptionList($description),
|
1238
|
+
'<p>' . $description . '</p>', $topic->LineNumber(),
|
1239
|
+
undef );
|
1240
|
+
};
|
1241
|
+
|
1242
|
+
$bodyIndex = $endList + 5;
|
1243
|
+
};
|
1244
|
+
|
1245
|
+
$newBody .= substr($body, $bodyIndex);
|
1246
|
+
|
1247
|
+
# Remove trailing headings.
|
1248
|
+
$newBody =~ s/(?:<h>[^<]+<\/h>)+$//;
|
1249
|
+
|
1250
|
+
# Remove empty headings.
|
1251
|
+
$newBody =~ s/(?:<h>[^<]+<\/h>)+(<h>[^<]+<\/h>)/$1/g;
|
1252
|
+
|
1253
|
+
if ($newBody)
|
1254
|
+
{
|
1255
|
+
unshift @newTopics, NaturalDocs::Parser::ParsedTopic->New( ::TOPIC_GROUP(), $topic->Title(), $topic->Package(),
|
1256
|
+
$topic->Using(), undef,
|
1257
|
+
$self->GetSummaryFromBody($newBody), $newBody,
|
1258
|
+
$topic->LineNumber(), undef );
|
1259
|
+
};
|
1260
|
+
|
1261
|
+
splice(@parsedFile, $index, 1, @newTopics);
|
1262
|
+
|
1263
|
+
$index += scalar @newTopics;
|
1264
|
+
}
|
1265
|
+
|
1266
|
+
else # not a list
|
1267
|
+
{ $index++; };
|
1268
|
+
};
|
1269
|
+
};
|
1270
|
+
|
1271
|
+
|
1272
|
+
#
|
1273
|
+
# Function: GetSummaryFromBody
|
1274
|
+
#
|
1275
|
+
# Returns the summary text from the topic body.
|
1276
|
+
#
|
1277
|
+
# Parameters:
|
1278
|
+
#
|
1279
|
+
# body - The complete topic body, in <NDMarkup>.
|
1280
|
+
#
|
1281
|
+
# Returns:
|
1282
|
+
#
|
1283
|
+
# The topic summary, or undef if none.
|
1284
|
+
#
|
1285
|
+
sub GetSummaryFromBody #(body)
|
1286
|
+
{
|
1287
|
+
my ($self, $body) = @_;
|
1288
|
+
|
1289
|
+
my $summary;
|
1290
|
+
|
1291
|
+
# Extract the first sentence from the leading paragraph, if any. We'll tolerate a single header beforehand, but nothing else.
|
1292
|
+
|
1293
|
+
if ($body =~ /^(?:<h>[^<]*<\/h>)?<p>(.*?)(<\/p>|[\.\!\?](?:[\)\}\'\ ]|"|>))/x)
|
1294
|
+
{
|
1295
|
+
$summary = $1;
|
1296
|
+
|
1297
|
+
if ($2 ne '</p>')
|
1298
|
+
{ $summary .= $2; };
|
1299
|
+
};
|
1300
|
+
|
1301
|
+
return $summary;
|
1302
|
+
};
|
1303
|
+
|
1304
|
+
|
1305
|
+
#
|
1306
|
+
# Function: GetSummaryFromDescriptionList
|
1307
|
+
#
|
1308
|
+
# Returns the summary text from a description list entry.
|
1309
|
+
#
|
1310
|
+
# Parameters:
|
1311
|
+
#
|
1312
|
+
# description - The description in <NDMarkup>. Should be the content between the <dd></dd> tags only.
|
1313
|
+
#
|
1314
|
+
# Returns:
|
1315
|
+
#
|
1316
|
+
# The description summary, or undef if none.
|
1317
|
+
#
|
1318
|
+
sub GetSummaryFromDescriptionList #(description)
|
1319
|
+
{
|
1320
|
+
my ($self, $description) = @_;
|
1321
|
+
|
1322
|
+
my $summary;
|
1323
|
+
|
1324
|
+
if ($description =~ /^(.*?)($|[\.\!\?](?:[\)\}\'\ ]|"|>))/)
|
1325
|
+
{ $summary = $1 . $2; };
|
1326
|
+
|
1327
|
+
return $summary;
|
1328
|
+
};
|
1329
|
+
|
1330
|
+
|
1331
|
+
1;
|