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,3693 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::Builder::HTMLBase
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A base package for all the shared functionality in <NaturalDocs::Builder::HTML> and
|
8
|
+
# <NaturalDocs::Builder::FramedHTML>.
|
9
|
+
#
|
10
|
+
###############################################################################
|
11
|
+
|
12
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
13
|
+
# Natural Docs is licensed under the GPL
|
14
|
+
|
15
|
+
|
16
|
+
use Tie::RefHash;
|
17
|
+
|
18
|
+
use strict;
|
19
|
+
use integer;
|
20
|
+
|
21
|
+
package NaturalDocs::Builder::HTMLBase;
|
22
|
+
|
23
|
+
use base 'NaturalDocs::Builder::Base';
|
24
|
+
|
25
|
+
use NaturalDocs::DefineMembers 'MADE_EMPTY_SEARCH_RESULTS_PAGE', 'MadeEmptySearchResultsPage()',
|
26
|
+
'SetMadeEmptySearchResultsPage()';
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
###############################################################################
|
31
|
+
# Group: Object Variables
|
32
|
+
|
33
|
+
|
34
|
+
#
|
35
|
+
# Constants: Members
|
36
|
+
#
|
37
|
+
# The object is implemented as a blessed arrayref, with the follow constants as indexes.
|
38
|
+
#
|
39
|
+
# MADE_EMPTY_SEARCH_RESULTS_PAGE - Whether the search results page for searches with no results was generated.
|
40
|
+
#
|
41
|
+
|
42
|
+
#
|
43
|
+
# Constants: NDMarkupToHTML Styles
|
44
|
+
#
|
45
|
+
# These are the styles used with <NDMarkupToHTML()>.
|
46
|
+
#
|
47
|
+
# NDMARKUPTOHTML_GENERAL - General style.
|
48
|
+
# NDMARKUPTOHTML_SUMMARY - For summaries.
|
49
|
+
# NDMARKUPTOHTML_TOOLTIP - For tooltips.
|
50
|
+
#
|
51
|
+
use constant NDMARKUPTOHTML_GENERAL => undef;
|
52
|
+
use constant NDMARKUPTOHTML_SUMMARY => 1;
|
53
|
+
use constant NDMARKUPTOHTML_TOOLTIP => 2;
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
###############################################################################
|
58
|
+
# Group: Package Variables
|
59
|
+
# These variables are shared by all instances of the package so don't change them.
|
60
|
+
|
61
|
+
|
62
|
+
#
|
63
|
+
# handle: FH_CSS_FILE
|
64
|
+
#
|
65
|
+
# The file handle to use when updating CSS files.
|
66
|
+
#
|
67
|
+
|
68
|
+
|
69
|
+
#
|
70
|
+
# Hash: abbreviations
|
71
|
+
#
|
72
|
+
# An existence hash of acceptable abbreviations. These are words that <AddDoubleSpaces()> won't put a second space
|
73
|
+
# after when followed by period-whitespace-capital letter. Yes, this is seriously over-engineered.
|
74
|
+
#
|
75
|
+
my %abbreviations = ( mr => 1, mrs => 1, ms => 1, dr => 1,
|
76
|
+
rev => 1, fr => 1, 'i.e' => 1,
|
77
|
+
maj => 1, gen => 1, pres => 1, sen => 1, rep => 1,
|
78
|
+
n => 1, s => 1, e => 1, w => 1, ne => 1, se => 1, nw => 1, sw => 1 );
|
79
|
+
|
80
|
+
#
|
81
|
+
# array: indexHeadings
|
82
|
+
#
|
83
|
+
# An array of the headings of all the index sections. First is for symbols, second for numbers, and the rest for each letter.
|
84
|
+
#
|
85
|
+
my @indexHeadings = ( '$#!', '0-9', 'A' .. 'Z' );
|
86
|
+
|
87
|
+
#
|
88
|
+
# array: indexAnchors
|
89
|
+
#
|
90
|
+
# An array of the HTML anchors of all the index sections. First is for symbols, second for numbers, and the rest for each letter.
|
91
|
+
#
|
92
|
+
my @indexAnchors = ( 'Symbols', 'Numbers', 'A' .. 'Z' );
|
93
|
+
|
94
|
+
#
|
95
|
+
# array: searchExtensions
|
96
|
+
#
|
97
|
+
# An array of the search file name extensions for all the index sections. First is for symbols, second for numbers, and the rest
|
98
|
+
# for each letter.
|
99
|
+
#
|
100
|
+
my @searchExtensions = ( 'Symbols', 'Numbers', 'A' .. 'Z' );
|
101
|
+
|
102
|
+
#
|
103
|
+
# bool: saidUpdatingCSSFile
|
104
|
+
#
|
105
|
+
# Whether the status message "Updating CSS file..." has been displayed. We only want to print it once, no matter how many
|
106
|
+
# HTML-based targets we are building.
|
107
|
+
#
|
108
|
+
my $saidUpdatingCSSFile;
|
109
|
+
|
110
|
+
#
|
111
|
+
# constant: ADD_HIDDEN_BREAKS
|
112
|
+
#
|
113
|
+
# Just a synonym for "1" so that setting the flag on <StringToHTML()> is clearer in the calling code.
|
114
|
+
#
|
115
|
+
use constant ADD_HIDDEN_BREAKS => 1;
|
116
|
+
|
117
|
+
|
118
|
+
###############################################################################
|
119
|
+
# Group: ToolTip Package Variables
|
120
|
+
#
|
121
|
+
# These variables are for the tooltip generation functions only. Since they're reset on every call to <BuildContent()> and
|
122
|
+
# <BuildIndexSections()>, and are only used by them and their support functions, they can be shared by all instances of the
|
123
|
+
# package.
|
124
|
+
|
125
|
+
#
|
126
|
+
# int: tooltipLinkNumber
|
127
|
+
#
|
128
|
+
# A number used as part of the ID for each link that has a tooltip. Should be incremented whenever one is made.
|
129
|
+
#
|
130
|
+
my $tooltipLinkNumber;
|
131
|
+
|
132
|
+
#
|
133
|
+
# int: tooltipNumber
|
134
|
+
#
|
135
|
+
# A number used as part of the ID for each tooltip. Should be incremented whenever one is made.
|
136
|
+
#
|
137
|
+
my $tooltipNumber;
|
138
|
+
|
139
|
+
#
|
140
|
+
# hash: tooltipSymbolsToNumbers
|
141
|
+
#
|
142
|
+
# A hash that maps the tooltip symbols to their assigned numbers.
|
143
|
+
#
|
144
|
+
my %tooltipSymbolsToNumbers;
|
145
|
+
|
146
|
+
#
|
147
|
+
# string: tooltipHTML
|
148
|
+
#
|
149
|
+
# The generated tooltip HTML.
|
150
|
+
#
|
151
|
+
my $tooltipHTML;
|
152
|
+
|
153
|
+
|
154
|
+
###############################################################################
|
155
|
+
# Group: Menu Package Variables
|
156
|
+
#
|
157
|
+
# These variables are for the menu generation functions only. Since they're reset on every call to <BuildMenu()> and are
|
158
|
+
# only used by it and its support functions, they can be shared by all instances of the package.
|
159
|
+
#
|
160
|
+
|
161
|
+
|
162
|
+
#
|
163
|
+
# hash: prebuiltMenus
|
164
|
+
#
|
165
|
+
# A hash that maps output directonies to menu HTML already built for it. There will be no selection or JavaScript in the menus.
|
166
|
+
#
|
167
|
+
my %prebuiltMenus;
|
168
|
+
|
169
|
+
|
170
|
+
#
|
171
|
+
# bool: menuNumbersAndLengthsDone
|
172
|
+
#
|
173
|
+
# Set when the variables that only need to be calculated for the menu once are done. This includes <menuGroupNumber>,
|
174
|
+
# <menuLength>, <menuGroupLengths>, and <menuGroupNumbers>, and <menuRootLength>.
|
175
|
+
#
|
176
|
+
my $menuNumbersAndLengthsDone;
|
177
|
+
|
178
|
+
|
179
|
+
#
|
180
|
+
# int: menuGroupNumber
|
181
|
+
#
|
182
|
+
# The current menu group number. Each time a group is created, this is incremented so that each one will be unique.
|
183
|
+
#
|
184
|
+
my $menuGroupNumber;
|
185
|
+
|
186
|
+
|
187
|
+
#
|
188
|
+
# int: menuLength
|
189
|
+
#
|
190
|
+
# The length of the entire menu, fully expanded. The value is computed from the <Menu Length Constants>.
|
191
|
+
#
|
192
|
+
my $menuLength;
|
193
|
+
|
194
|
+
|
195
|
+
#
|
196
|
+
# hash: menuGroupLengths
|
197
|
+
#
|
198
|
+
# A hash of the length of each group, *not* including any subgroup contents. The keys are references to each groups'
|
199
|
+
# <NaturalDocs::Menu::Entry> object, and the values are their lengths computed from the <Menu Length Constants>.
|
200
|
+
#
|
201
|
+
my %menuGroupLengths;
|
202
|
+
tie %menuGroupLengths, 'Tie::RefHash';
|
203
|
+
|
204
|
+
|
205
|
+
#
|
206
|
+
# hash: menuGroupNumbers
|
207
|
+
#
|
208
|
+
# A hash of the number of each group, as managed by <menuGroupNumber>. The keys are references to each groups'
|
209
|
+
# <NaturalDocs::Menu::Entry> object, and the values are the number.
|
210
|
+
#
|
211
|
+
my %menuGroupNumbers;
|
212
|
+
tie %menuGroupNumbers, 'Tie::RefHash';
|
213
|
+
|
214
|
+
|
215
|
+
#
|
216
|
+
# int: menuRootLength
|
217
|
+
#
|
218
|
+
# The length of the top-level menu entries without expansion. The value is computed from the <Menu Length Constants>.
|
219
|
+
#
|
220
|
+
my $menuRootLength;
|
221
|
+
|
222
|
+
|
223
|
+
#
|
224
|
+
# constants: Menu Length Constants
|
225
|
+
#
|
226
|
+
# Constants used to approximate the lengths of the menu or its groups.
|
227
|
+
#
|
228
|
+
# MENU_TITLE_LENGTH - The length of the title.
|
229
|
+
# MENU_SUBTITLE_LENGTH - The length of the subtitle.
|
230
|
+
# MENU_FILE_LENGTH - The length of one file entry.
|
231
|
+
# MENU_GROUP_LENGTH - The length of one group entry.
|
232
|
+
# MENU_TEXT_LENGTH - The length of one text entry.
|
233
|
+
# MENU_LINK_LENGTH - The length of one link entry.
|
234
|
+
#
|
235
|
+
# MENU_LENGTH_LIMIT - The limit of the menu's length. If the total length surpasses this limit, groups that aren't required
|
236
|
+
# to be open to show the selection will default to closed on browsers that support it.
|
237
|
+
#
|
238
|
+
use constant MENU_TITLE_LENGTH => 3;
|
239
|
+
use constant MENU_SUBTITLE_LENGTH => 1;
|
240
|
+
use constant MENU_FILE_LENGTH => 1;
|
241
|
+
use constant MENU_GROUP_LENGTH => 2; # because it's a line and a blank space
|
242
|
+
use constant MENU_TEXT_LENGTH => 1;
|
243
|
+
use constant MENU_LINK_LENGTH => 1;
|
244
|
+
use constant MENU_INDEX_LENGTH => 1;
|
245
|
+
|
246
|
+
use constant MENU_LENGTH_LIMIT => 35;
|
247
|
+
|
248
|
+
|
249
|
+
###############################################################################
|
250
|
+
# Group: Image Package Variables
|
251
|
+
#
|
252
|
+
# These variables are for the image generation functions only. Since they're reset on every call to <BuildContent()>,
|
253
|
+
# and are only used by it and its support functions, they can be shared by all instances of thepackage.
|
254
|
+
|
255
|
+
|
256
|
+
#
|
257
|
+
# var: imageAnchorNumber
|
258
|
+
# Incremented for each image link in the file that requires an anchor.
|
259
|
+
#
|
260
|
+
my $imageAnchorNumber;
|
261
|
+
|
262
|
+
|
263
|
+
#
|
264
|
+
# var: imageContent
|
265
|
+
#
|
266
|
+
# The actual embedded image HTML for all image links. When generating an image link, the link HTML is returned and
|
267
|
+
# the HTML for the target image is added here. Periodically, such as after the end of the paragraph, this content should
|
268
|
+
# be added to the page and the variable set to undef.
|
269
|
+
#
|
270
|
+
my $imageContent;
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
###############################################################################
|
275
|
+
# Group: Search Package Variables
|
276
|
+
#
|
277
|
+
# These variables are for the search generation functions only. Since they're reset on every call to <BuildIndexSections()> and
|
278
|
+
# are only used by them and their support functions, they can be shared by all instances of the package.
|
279
|
+
|
280
|
+
|
281
|
+
#
|
282
|
+
# hash: searchResultIDs
|
283
|
+
#
|
284
|
+
# A hash mapping lowercase-only search result IDs to the number of times they've been used. This is to work around an IE
|
285
|
+
# bug where it won't correctly reference IDs if they differ only in case.
|
286
|
+
#
|
287
|
+
my %searchResultIDs;
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
###############################################################################
|
292
|
+
# Group: Object Functions
|
293
|
+
|
294
|
+
|
295
|
+
#
|
296
|
+
# Function: New
|
297
|
+
# Creates and returns a new object.
|
298
|
+
#
|
299
|
+
sub New
|
300
|
+
{
|
301
|
+
my $class = shift;
|
302
|
+
|
303
|
+
my $object = $class->SUPER::New();
|
304
|
+
$object->SetMadeEmptySearchResultsPage(0);
|
305
|
+
|
306
|
+
return $object;
|
307
|
+
};
|
308
|
+
|
309
|
+
|
310
|
+
# Function: MadeEmptySearchResultsPage
|
311
|
+
# Returns whether the empty search results page was created or not.
|
312
|
+
|
313
|
+
# Function: SetMadeEmptySearchResultsPage
|
314
|
+
# Sets whether the empty search results page was created or not.
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
###############################################################################
|
319
|
+
# Group: Implemented Interface Functions
|
320
|
+
#
|
321
|
+
# The behavior of these functions is shared between HTML output formats.
|
322
|
+
#
|
323
|
+
|
324
|
+
|
325
|
+
#
|
326
|
+
# Function: UpdateImage
|
327
|
+
#
|
328
|
+
# Define this function to add or update the passed image in the output.
|
329
|
+
#
|
330
|
+
# Parameters:
|
331
|
+
#
|
332
|
+
# file - The image <FileName>
|
333
|
+
#
|
334
|
+
sub UpdateImage #(file)
|
335
|
+
{
|
336
|
+
my ($self, $file) = @_;
|
337
|
+
|
338
|
+
my $outputFile = $self->OutputImageOf($file);
|
339
|
+
my $outputDirectory = NaturalDocs::File->NoFileName($outputFile);
|
340
|
+
|
341
|
+
if (!-d $outputDirectory)
|
342
|
+
{ NaturalDocs::File->CreatePath($outputDirectory); };
|
343
|
+
|
344
|
+
NaturalDocs::File->Copy($file, $outputFile);
|
345
|
+
};
|
346
|
+
|
347
|
+
|
348
|
+
#
|
349
|
+
# Function: PurgeFiles
|
350
|
+
#
|
351
|
+
# Deletes the output files associated with the purged source files.
|
352
|
+
#
|
353
|
+
sub PurgeFiles #(filesToPurge)
|
354
|
+
{
|
355
|
+
my ($self, $filesToPurge) = @_;
|
356
|
+
|
357
|
+
# Combine directories into a hash to remove duplicate work.
|
358
|
+
my %directoriesToPurge;
|
359
|
+
|
360
|
+
foreach my $file (keys %$filesToPurge)
|
361
|
+
{
|
362
|
+
# It's possible that there may be files there that aren't in a valid input directory anymore. They won't generate an output
|
363
|
+
# file name so we need to check for undef.
|
364
|
+
my $outputFile = $self->OutputFileOf($file);
|
365
|
+
if (defined $outputFile)
|
366
|
+
{
|
367
|
+
unlink($outputFile);
|
368
|
+
$directoriesToPurge{ NaturalDocs::File->NoFileName($outputFile) } = 1;
|
369
|
+
};
|
370
|
+
};
|
371
|
+
|
372
|
+
foreach my $directory (keys %directoriesToPurge)
|
373
|
+
{
|
374
|
+
NaturalDocs::File->RemoveEmptyTree($directory, NaturalDocs::Settings->OutputDirectoryOf($self));
|
375
|
+
};
|
376
|
+
};
|
377
|
+
|
378
|
+
|
379
|
+
#
|
380
|
+
# Function: PurgeIndexes
|
381
|
+
#
|
382
|
+
# Deletes the output files associated with the purged source files.
|
383
|
+
#
|
384
|
+
# Parameters:
|
385
|
+
#
|
386
|
+
# indexes - An existence hashref of the index types to purge. The keys are the <TopicTypes> or * for the general index.
|
387
|
+
#
|
388
|
+
sub PurgeIndexes #(indexes)
|
389
|
+
{
|
390
|
+
my ($self, $indexes) = @_;
|
391
|
+
|
392
|
+
foreach my $index (keys %$indexes)
|
393
|
+
{
|
394
|
+
$self->PurgeIndexFiles($index, undef, undef);
|
395
|
+
};
|
396
|
+
};
|
397
|
+
|
398
|
+
|
399
|
+
#
|
400
|
+
# Function: PurgeImages
|
401
|
+
#
|
402
|
+
# Define this function to make the package remove all output related to the passed image files. These files are no longer used
|
403
|
+
# by the documentation.
|
404
|
+
#
|
405
|
+
# Parameters:
|
406
|
+
#
|
407
|
+
# files - An existence hashref of the image <FileNames> to purge.
|
408
|
+
#
|
409
|
+
sub PurgeImages #(files)
|
410
|
+
{
|
411
|
+
my ($self, $filesToPurge) = @_;
|
412
|
+
|
413
|
+
# Combine directories into a hash to remove duplicate work.
|
414
|
+
my %directoriesToPurge;
|
415
|
+
|
416
|
+
foreach my $file (keys %$filesToPurge)
|
417
|
+
{
|
418
|
+
# It's possible that there may be files there that aren't in a valid input directory anymore. They won't generate an output
|
419
|
+
# file name so we need to check for undef.
|
420
|
+
my $outputFile = $self->OutputImageOf($file);
|
421
|
+
if (defined $outputFile)
|
422
|
+
{
|
423
|
+
unlink($outputFile);
|
424
|
+
$directoriesToPurge{ NaturalDocs::File->NoFileName($outputFile) } = 1;
|
425
|
+
};
|
426
|
+
};
|
427
|
+
|
428
|
+
foreach my $directory (keys %directoriesToPurge)
|
429
|
+
{
|
430
|
+
NaturalDocs::File->RemoveEmptyTree($directory, NaturalDocs::Settings->OutputDirectoryOf($self));
|
431
|
+
};
|
432
|
+
};
|
433
|
+
|
434
|
+
|
435
|
+
#
|
436
|
+
# Function: BeginBuild
|
437
|
+
#
|
438
|
+
# Creates the necessary subdirectories in the output directory.
|
439
|
+
#
|
440
|
+
sub BeginBuild #(hasChanged)
|
441
|
+
{
|
442
|
+
my ($self, $hasChanged) = @_;
|
443
|
+
|
444
|
+
foreach my $directory ( $self->JavaScriptDirectory(), $self->CSSDirectory(), $self->IndexDirectory(),
|
445
|
+
$self->SearchResultsDirectory() )
|
446
|
+
{
|
447
|
+
if (!-d $directory)
|
448
|
+
{ NaturalDocs::File->CreatePath($directory); };
|
449
|
+
};
|
450
|
+
};
|
451
|
+
|
452
|
+
|
453
|
+
#
|
454
|
+
# Function: EndBuild
|
455
|
+
#
|
456
|
+
# Synchronizes the projects CSS and JavaScript files. Also generates the search data JavaScript file.
|
457
|
+
#
|
458
|
+
sub EndBuild #(hasChanged)
|
459
|
+
{
|
460
|
+
my ($self, $hasChanged) = @_;
|
461
|
+
|
462
|
+
|
463
|
+
# Update the style sheets.
|
464
|
+
|
465
|
+
my $styles = NaturalDocs::Settings->Styles();
|
466
|
+
my $changed;
|
467
|
+
|
468
|
+
my $cssDirectory = $self->CSSDirectory();
|
469
|
+
my $mainCSSFile = $self->MainCSSFile();
|
470
|
+
|
471
|
+
for (my $i = 0; $i < scalar @$styles; $i++)
|
472
|
+
{
|
473
|
+
my $outputCSSFile;
|
474
|
+
|
475
|
+
if (scalar @$styles == 1)
|
476
|
+
{ $outputCSSFile = $mainCSSFile; }
|
477
|
+
else
|
478
|
+
{ $outputCSSFile = NaturalDocs::File->JoinPaths($cssDirectory, ($i + 1) . '.css'); };
|
479
|
+
|
480
|
+
|
481
|
+
my $masterCSSFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), $styles->[$i] . '.css' );
|
482
|
+
|
483
|
+
if (! -e $masterCSSFile)
|
484
|
+
{ $masterCSSFile = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->StyleDirectory(), $styles->[$i] . '.css' ); };
|
485
|
+
|
486
|
+
# We check both the date and the size in case the user switches between two styles which just happen to have the same
|
487
|
+
# date. Should rarely happen, but it might.
|
488
|
+
if (! -e $outputCSSFile ||
|
489
|
+
(stat($masterCSSFile))[9] != (stat($outputCSSFile))[9] ||
|
490
|
+
-s $masterCSSFile != -s $outputCSSFile)
|
491
|
+
{
|
492
|
+
if (!NaturalDocs::Settings->IsQuiet() && !$saidUpdatingCSSFile)
|
493
|
+
{
|
494
|
+
print "Updating CSS file...\n";
|
495
|
+
$saidUpdatingCSSFile = 1;
|
496
|
+
};
|
497
|
+
|
498
|
+
NaturalDocs::File->Copy($masterCSSFile, $outputCSSFile);
|
499
|
+
|
500
|
+
$changed = 1;
|
501
|
+
};
|
502
|
+
};
|
503
|
+
|
504
|
+
|
505
|
+
my $deleteFrom;
|
506
|
+
|
507
|
+
if (scalar @$styles == 1)
|
508
|
+
{ $deleteFrom = 1; }
|
509
|
+
else
|
510
|
+
{ $deleteFrom = scalar @$styles + 1; };
|
511
|
+
|
512
|
+
for (;;)
|
513
|
+
{
|
514
|
+
my $file = NaturalDocs::File->JoinPaths($cssDirectory, $deleteFrom . '.css');
|
515
|
+
|
516
|
+
if (! -e $file)
|
517
|
+
{ last; };
|
518
|
+
|
519
|
+
unlink ($file);
|
520
|
+
$deleteFrom++;
|
521
|
+
|
522
|
+
$changed = 1;
|
523
|
+
};
|
524
|
+
|
525
|
+
|
526
|
+
if ($changed)
|
527
|
+
{
|
528
|
+
if (scalar @$styles > 1)
|
529
|
+
{
|
530
|
+
open(FH_CSS_FILE, '>' . $mainCSSFile);
|
531
|
+
|
532
|
+
for (my $i = 0; $i < scalar @$styles; $i++)
|
533
|
+
{
|
534
|
+
print FH_CSS_FILE '@import URL("' . ($i + 1) . '.css");' . "\n";
|
535
|
+
};
|
536
|
+
|
537
|
+
close(FH_CSS_FILE);
|
538
|
+
};
|
539
|
+
};
|
540
|
+
|
541
|
+
|
542
|
+
|
543
|
+
# Update the JavaScript files
|
544
|
+
|
545
|
+
my $jsMaster = NaturalDocs::File->JoinPaths( NaturalDocs::Settings->JavaScriptDirectory(), 'NaturalDocs.js' );
|
546
|
+
my $jsOutput = $self->MainJavaScriptFile();
|
547
|
+
|
548
|
+
# We check both the date and the size in case the user switches between two styles which just happen to have the same
|
549
|
+
# date. Should rarely happen, but it might.
|
550
|
+
if (! -e $jsOutput ||
|
551
|
+
(stat($jsMaster))[9] != (stat($jsOutput))[9] ||
|
552
|
+
-s $jsMaster != -s $jsOutput)
|
553
|
+
{
|
554
|
+
NaturalDocs::File->Copy($jsMaster, $jsOutput);
|
555
|
+
};
|
556
|
+
|
557
|
+
|
558
|
+
my @indexes = keys %{NaturalDocs::Menu->Indexes()};
|
559
|
+
|
560
|
+
open(FH_INDEXINFOJS, '>' . NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'searchdata.js'));
|
561
|
+
|
562
|
+
print FH_INDEXINFOJS
|
563
|
+
"var indexSectionsWithContent = {\n";
|
564
|
+
|
565
|
+
for (my $i = 0; $i < scalar @indexes; $i++)
|
566
|
+
{
|
567
|
+
if ($i != 0)
|
568
|
+
{ print FH_INDEXINFOJS ",\n"; };
|
569
|
+
|
570
|
+
print FH_INDEXINFOJS ' "' . NaturalDocs::Topics->NameOfType($indexes[$i], 1, 1) . "\": {\n";
|
571
|
+
|
572
|
+
my $content = NaturalDocs::SymbolTable->IndexSectionsWithContent($indexes[$i]);
|
573
|
+
for (my $contentIndex = 0; $contentIndex < 28; $contentIndex++)
|
574
|
+
{
|
575
|
+
if ($contentIndex != 0)
|
576
|
+
{ print FH_INDEXINFOJS ",\n"; };
|
577
|
+
|
578
|
+
print FH_INDEXINFOJS ' "' . $searchExtensions[$contentIndex] . '": ' . ($content->[$contentIndex] ? 'true' : 'false');
|
579
|
+
};
|
580
|
+
|
581
|
+
print FH_INDEXINFOJS "\n }";
|
582
|
+
};
|
583
|
+
|
584
|
+
print FH_INDEXINFOJS
|
585
|
+
"\n }";
|
586
|
+
|
587
|
+
close(FH_INDEXINFOJS);
|
588
|
+
};
|
589
|
+
|
590
|
+
|
591
|
+
|
592
|
+
###############################################################################
|
593
|
+
# Group: Section Functions
|
594
|
+
|
595
|
+
|
596
|
+
#
|
597
|
+
# Function: BuildTitle
|
598
|
+
#
|
599
|
+
# Builds and returns the HTML page title of a file.
|
600
|
+
#
|
601
|
+
# Parameters:
|
602
|
+
#
|
603
|
+
# sourceFile - The source <FileName> to build the title of.
|
604
|
+
#
|
605
|
+
# Returns:
|
606
|
+
#
|
607
|
+
# The source file's title in HTML.
|
608
|
+
#
|
609
|
+
sub BuildTitle #(sourceFile)
|
610
|
+
{
|
611
|
+
my ($self, $sourceFile) = @_;
|
612
|
+
|
613
|
+
# If we have a menu title, the page title is [menu title] - [file title]. Otherwise it is just [file title].
|
614
|
+
|
615
|
+
my $title = NaturalDocs::Project->DefaultMenuTitleOf($sourceFile);
|
616
|
+
|
617
|
+
my $menuTitle = NaturalDocs::Menu->Title();
|
618
|
+
if (defined $menuTitle && $menuTitle ne $title)
|
619
|
+
{ $title .= ' - ' . $menuTitle; };
|
620
|
+
|
621
|
+
$title = $self->StringToHTML($title);
|
622
|
+
|
623
|
+
return $title;
|
624
|
+
};
|
625
|
+
|
626
|
+
#
|
627
|
+
# Function: BuildMenu
|
628
|
+
#
|
629
|
+
# Builds and returns the side menu of a file.
|
630
|
+
#
|
631
|
+
# Parameters:
|
632
|
+
#
|
633
|
+
# sourceFile - The source <FileName> to use if you're looking for a source file.
|
634
|
+
# indexType - The index <TopicType> to use if you're looking for an index.
|
635
|
+
#
|
636
|
+
# Both sourceFile and indexType may be undef.
|
637
|
+
#
|
638
|
+
# Returns:
|
639
|
+
#
|
640
|
+
# The side menu in HTML.
|
641
|
+
#
|
642
|
+
# Dependencies:
|
643
|
+
#
|
644
|
+
# - <Builder::HTML::UpdateFile()> and <Builder::HTML::UpdateIndex()> require this section to be surrounded with the exact
|
645
|
+
# strings "<div id=Menu>" and "</div><!--Menu-->".
|
646
|
+
# - This function depends on the way <BuildMenuSegment()> formats file and index entries.
|
647
|
+
#
|
648
|
+
sub BuildMenu #(FileName sourceFile, TopicType indexType) -> string htmlMenu
|
649
|
+
{
|
650
|
+
my ($self, $sourceFile, $indexType) = @_;
|
651
|
+
|
652
|
+
if (!$menuNumbersAndLengthsDone)
|
653
|
+
{
|
654
|
+
$menuGroupNumber = 1;
|
655
|
+
$menuLength = 0;
|
656
|
+
%menuGroupLengths = ( );
|
657
|
+
%menuGroupNumbers = ( );
|
658
|
+
$menuRootLength = 0;
|
659
|
+
};
|
660
|
+
|
661
|
+
my $outputDirectory;
|
662
|
+
|
663
|
+
if ($sourceFile)
|
664
|
+
{ $outputDirectory = NaturalDocs::File->NoFileName( $self->OutputFileOf($sourceFile) ); }
|
665
|
+
elsif ($indexType)
|
666
|
+
{ $outputDirectory = NaturalDocs::File->NoFileName( $self->IndexFileOf($indexType) ); }
|
667
|
+
else
|
668
|
+
{ $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self); };
|
669
|
+
|
670
|
+
|
671
|
+
# Comment needed for UpdateFile().
|
672
|
+
my $output = '<div id=Menu>';
|
673
|
+
|
674
|
+
|
675
|
+
if (!exists $prebuiltMenus{$outputDirectory})
|
676
|
+
{
|
677
|
+
my $segmentOutput;
|
678
|
+
|
679
|
+
($segmentOutput, $menuRootLength) =
|
680
|
+
$self->BuildMenuSegment($outputDirectory, NaturalDocs::Menu->Content(), 1);
|
681
|
+
|
682
|
+
my $titleOutput;
|
683
|
+
|
684
|
+
my $menuTitle = NaturalDocs::Menu->Title();
|
685
|
+
if (defined $menuTitle)
|
686
|
+
{
|
687
|
+
if (!$menuNumbersAndLengthsDone)
|
688
|
+
{ $menuLength += MENU_TITLE_LENGTH; };
|
689
|
+
|
690
|
+
$menuRootLength += MENU_TITLE_LENGTH;
|
691
|
+
|
692
|
+
$titleOutput .=
|
693
|
+
'<div class=MTitle>'
|
694
|
+
. $self->StringToHTML($menuTitle);
|
695
|
+
|
696
|
+
my $menuSubTitle = NaturalDocs::Menu->SubTitle();
|
697
|
+
if (defined $menuSubTitle)
|
698
|
+
{
|
699
|
+
if (!$menuNumbersAndLengthsDone)
|
700
|
+
{ $menuLength += MENU_SUBTITLE_LENGTH; };
|
701
|
+
|
702
|
+
$menuRootLength += MENU_SUBTITLE_LENGTH;
|
703
|
+
|
704
|
+
$titleOutput .=
|
705
|
+
'<div class=MSubTitle>'
|
706
|
+
. $self->StringToHTML($menuSubTitle)
|
707
|
+
. '</div>';
|
708
|
+
};
|
709
|
+
|
710
|
+
$titleOutput .=
|
711
|
+
'</div>';
|
712
|
+
};
|
713
|
+
|
714
|
+
my $searchOutput;
|
715
|
+
|
716
|
+
if (scalar keys %{NaturalDocs::Menu->Indexes()})
|
717
|
+
{
|
718
|
+
$searchOutput =
|
719
|
+
'<script type="text/javascript"><!--' . "\n"
|
720
|
+
. 'var searchPanel = new SearchPanel("searchPanel", "' . $self->CommandLineOption() . '", '
|
721
|
+
. '"' . $self->MakeRelativeURL($outputDirectory, $self->SearchResultsDirectory()) . '");' . "\n"
|
722
|
+
. '--></script>'
|
723
|
+
|
724
|
+
. '<div id=MSearchPanel class=MSearchPanelInactive>'
|
725
|
+
. '<input type=text id=MSearchField value=Search '
|
726
|
+
. 'onFocus="searchPanel.OnSearchFieldFocus(true)" onBlur="searchPanel.OnSearchFieldFocus(false)" '
|
727
|
+
. 'onKeyUp="searchPanel.OnSearchFieldChange()">'
|
728
|
+
. '<select id=MSearchType '
|
729
|
+
. 'onFocus="searchPanel.OnSearchTypeFocus(true)" onBlur="searchPanel.OnSearchTypeFocus(false)" '
|
730
|
+
. 'onChange="searchPanel.OnSearchTypeChange()">';
|
731
|
+
|
732
|
+
my @indexes = keys %{NaturalDocs::Menu->Indexes()};
|
733
|
+
@indexes = sort
|
734
|
+
{
|
735
|
+
if ($a eq ::TOPIC_GENERAL()) { return -1; }
|
736
|
+
elsif ($b eq ::TOPIC_GENERAL()) { return 1; }
|
737
|
+
else { return (NaturalDocs::Topics->NameOfType($a, 1) cmp NaturalDocs::Topics->NameOfType($b, 1)) };
|
738
|
+
} @indexes;
|
739
|
+
|
740
|
+
foreach my $index (@indexes)
|
741
|
+
{
|
742
|
+
my ($name, $extra);
|
743
|
+
if ($index eq ::TOPIC_GENERAL())
|
744
|
+
{
|
745
|
+
$name = 'Everything';
|
746
|
+
$extra = ' id=MSearchEverything selected ';
|
747
|
+
}
|
748
|
+
else
|
749
|
+
{ $name = $self->ConvertAmpChars(NaturalDocs::Topics->NameOfType($index, 1)); }
|
750
|
+
|
751
|
+
$searchOutput .=
|
752
|
+
'<option ' . $extra . 'value="' . NaturalDocs::Topics->NameOfType($index, 1, 1) . '">'
|
753
|
+
. $name
|
754
|
+
. '</option>';
|
755
|
+
};
|
756
|
+
|
757
|
+
$searchOutput .=
|
758
|
+
'</select>'
|
759
|
+
. '</div>';
|
760
|
+
};
|
761
|
+
|
762
|
+
$prebuiltMenus{$outputDirectory} = $titleOutput . $segmentOutput . $searchOutput;
|
763
|
+
$output .= $titleOutput . $segmentOutput . $searchOutput;
|
764
|
+
}
|
765
|
+
else
|
766
|
+
{ $output .= $prebuiltMenus{$outputDirectory}; };
|
767
|
+
|
768
|
+
|
769
|
+
# Highlight the menu selection.
|
770
|
+
|
771
|
+
if ($sourceFile)
|
772
|
+
{
|
773
|
+
# Dependency: This depends on how BuildMenuSegment() formats file entries.
|
774
|
+
my $outputFile = $self->OutputFileOf($sourceFile);
|
775
|
+
my $tag = '<div class=MFile><a href="' . $self->MakeRelativeURL($outputDirectory, $outputFile) . '">';
|
776
|
+
my $tagIndex = index($output, $tag);
|
777
|
+
|
778
|
+
if ($tagIndex != -1)
|
779
|
+
{
|
780
|
+
my $endIndex = index($output, '</a>', $tagIndex);
|
781
|
+
|
782
|
+
substr($output, $endIndex, 4, '');
|
783
|
+
substr($output, $tagIndex, length($tag), '<div class=MFile id=MSelected>');
|
784
|
+
};
|
785
|
+
}
|
786
|
+
elsif ($indexType)
|
787
|
+
{
|
788
|
+
# Dependency: This depends on how BuildMenuSegment() formats index entries.
|
789
|
+
my $outputFile = $self->IndexFileOf($indexType);
|
790
|
+
my $tag = '<div class=MIndex><a href="' . $self->MakeRelativeURL($outputDirectory, $outputFile) . '">';
|
791
|
+
my $tagIndex = index($output, $tag);
|
792
|
+
|
793
|
+
if ($tagIndex != -1)
|
794
|
+
{
|
795
|
+
my $endIndex = index($output, '</a>', $tagIndex);
|
796
|
+
|
797
|
+
substr($output, $endIndex, 4, '');
|
798
|
+
substr($output, $tagIndex, length($tag), '<div class=MIndex id=MSelected>');
|
799
|
+
};
|
800
|
+
};
|
801
|
+
|
802
|
+
|
803
|
+
# If the completely expanded menu is too long, collapse all the groups that aren't in the selection hierarchy or near the
|
804
|
+
# selection. By doing this instead of having them default to closed via CSS, any browser that doesn't support changing this at
|
805
|
+
# runtime will keep the menu entirely open so that its still usable.
|
806
|
+
|
807
|
+
if ($menuLength > MENU_LENGTH_LIMIT())
|
808
|
+
{
|
809
|
+
my $menuSelectionHierarchy = $self->GetMenuSelectionHierarchy($sourceFile, $indexType);
|
810
|
+
|
811
|
+
my $toExpand = $self->ExpandMenu($sourceFile, $indexType, $menuSelectionHierarchy, $menuRootLength);
|
812
|
+
|
813
|
+
$output .=
|
814
|
+
|
815
|
+
'<script language=JavaScript><!--' . "\n"
|
816
|
+
|
817
|
+
. 'HideAllBut([' . join(', ', @$toExpand) . '], ' . $menuGroupNumber . ');'
|
818
|
+
|
819
|
+
. '// --></script>';
|
820
|
+
};
|
821
|
+
|
822
|
+
$output .= '</div><!--Menu-->';
|
823
|
+
|
824
|
+
$menuNumbersAndLengthsDone = 1;
|
825
|
+
|
826
|
+
return $output;
|
827
|
+
};
|
828
|
+
|
829
|
+
|
830
|
+
#
|
831
|
+
# Function: BuildMenuSegment
|
832
|
+
#
|
833
|
+
# A recursive function to build a segment of the menu. *Remember to reset the <Menu Package Variables> before calling this
|
834
|
+
# for the first time.*
|
835
|
+
#
|
836
|
+
# Parameters:
|
837
|
+
#
|
838
|
+
# outputDirectory - The output directory the menu is being built for.
|
839
|
+
# menuSegment - An arrayref specifying the segment of the menu to build. Either pass the menu itself or the contents
|
840
|
+
# of a group.
|
841
|
+
# topLevel - Whether the passed segment is the top level segment or not.
|
842
|
+
#
|
843
|
+
# Returns:
|
844
|
+
#
|
845
|
+
# The array ( menuHTML, length ).
|
846
|
+
#
|
847
|
+
# menuHTML - The menu segment in HTML.
|
848
|
+
# groupLength - The length of the group, *not* including the contents of any subgroups, as computed from the
|
849
|
+
# <Menu Length Constants>.
|
850
|
+
#
|
851
|
+
# Dependencies:
|
852
|
+
#
|
853
|
+
# - <BuildMenu()> depends on the way this function formats file and index entries.
|
854
|
+
#
|
855
|
+
sub BuildMenuSegment #(outputDirectory, menuSegment, topLevel)
|
856
|
+
{
|
857
|
+
my ($self, $outputDirectory, $menuSegment, $topLevel) = @_;
|
858
|
+
|
859
|
+
my $output;
|
860
|
+
my $groupLength = 0;
|
861
|
+
|
862
|
+
foreach my $entry (@$menuSegment)
|
863
|
+
{
|
864
|
+
if ($entry->Type() == ::MENU_GROUP())
|
865
|
+
{
|
866
|
+
my ($entryOutput, $entryLength) =
|
867
|
+
$self->BuildMenuSegment($outputDirectory, $entry->GroupContent());
|
868
|
+
|
869
|
+
my $entryNumber;
|
870
|
+
|
871
|
+
if (!$menuNumbersAndLengthsDone)
|
872
|
+
{
|
873
|
+
$entryNumber = $menuGroupNumber;
|
874
|
+
$menuGroupNumber++;
|
875
|
+
|
876
|
+
$menuGroupLengths{$entry} = $entryLength;
|
877
|
+
$menuGroupNumbers{$entry} = $entryNumber;
|
878
|
+
}
|
879
|
+
else
|
880
|
+
{ $entryNumber = $menuGroupNumbers{$entry}; };
|
881
|
+
|
882
|
+
$output .=
|
883
|
+
'<div class=MEntry>'
|
884
|
+
. '<div class=MGroup>'
|
885
|
+
|
886
|
+
. '<a href="javascript:ToggleMenu(\'MGroupContent' . $entryNumber . '\')"'
|
887
|
+
. ($self->CommandLineOption() eq 'FramedHTML' ? ' target="_self"' : '') . '>'
|
888
|
+
. $self->StringToHTML($entry->Title())
|
889
|
+
. '</a>'
|
890
|
+
|
891
|
+
. '<div class=MGroupContent id=MGroupContent' . $entryNumber . '>'
|
892
|
+
. $entryOutput
|
893
|
+
. '</div>'
|
894
|
+
|
895
|
+
. '</div>'
|
896
|
+
. '</div>';
|
897
|
+
|
898
|
+
$groupLength += MENU_GROUP_LENGTH;
|
899
|
+
}
|
900
|
+
|
901
|
+
elsif ($entry->Type() == ::MENU_FILE())
|
902
|
+
{
|
903
|
+
my $targetOutputFile = $self->OutputFileOf($entry->Target());
|
904
|
+
|
905
|
+
# Dependency: BuildMenu() depends on how this formats file entries.
|
906
|
+
$output .=
|
907
|
+
'<div class=MEntry>'
|
908
|
+
. '<div class=MFile>'
|
909
|
+
. '<a href="' . $self->MakeRelativeURL($outputDirectory, $targetOutputFile) . '">'
|
910
|
+
. $self->StringToHTML( $entry->Title(), ADD_HIDDEN_BREAKS)
|
911
|
+
. '</a>'
|
912
|
+
. '</div>'
|
913
|
+
. '</div>';
|
914
|
+
|
915
|
+
$groupLength += MENU_FILE_LENGTH;
|
916
|
+
}
|
917
|
+
|
918
|
+
elsif ($entry->Type() == ::MENU_TEXT())
|
919
|
+
{
|
920
|
+
$output .=
|
921
|
+
'<div class=MEntry>'
|
922
|
+
. '<div class=MText>'
|
923
|
+
. $self->StringToHTML( $entry->Title() )
|
924
|
+
. '</div>'
|
925
|
+
. '</div>';
|
926
|
+
|
927
|
+
$groupLength += MENU_TEXT_LENGTH;
|
928
|
+
}
|
929
|
+
|
930
|
+
elsif ($entry->Type() == ::MENU_LINK())
|
931
|
+
{
|
932
|
+
$output .=
|
933
|
+
'<div class=MEntry>'
|
934
|
+
. '<div class=MLink>'
|
935
|
+
. '<a href="' . $entry->Target() . '"' . ($self->CommandLineOption() eq 'FramedHTML' ? ' target="_top"' : '') . '>'
|
936
|
+
. $self->StringToHTML( $entry->Title() )
|
937
|
+
. '</a>'
|
938
|
+
. '</div>'
|
939
|
+
. '</div>';
|
940
|
+
|
941
|
+
$groupLength += MENU_LINK_LENGTH;
|
942
|
+
}
|
943
|
+
|
944
|
+
elsif ($entry->Type() == ::MENU_INDEX())
|
945
|
+
{
|
946
|
+
my $indexFile = $self->IndexFileOf($entry->Target);
|
947
|
+
|
948
|
+
# Dependency: BuildMenu() depends on how this formats index entries.
|
949
|
+
$output .=
|
950
|
+
'<div class=MEntry>'
|
951
|
+
. '<div class=MIndex>'
|
952
|
+
. '<a href="' . $self->MakeRelativeURL( $outputDirectory, $self->IndexFileOf($entry->Target()) ) . '">'
|
953
|
+
. $self->StringToHTML( $entry->Title() )
|
954
|
+
. '</a>'
|
955
|
+
. '</div>'
|
956
|
+
. '</div>';
|
957
|
+
|
958
|
+
$groupLength += MENU_INDEX_LENGTH;
|
959
|
+
};
|
960
|
+
};
|
961
|
+
|
962
|
+
|
963
|
+
if (!$menuNumbersAndLengthsDone)
|
964
|
+
{ $menuLength += $groupLength; };
|
965
|
+
|
966
|
+
return ($output, $groupLength);
|
967
|
+
};
|
968
|
+
|
969
|
+
|
970
|
+
#
|
971
|
+
# Function: BuildContent
|
972
|
+
#
|
973
|
+
# Builds and returns the main page content.
|
974
|
+
#
|
975
|
+
# Parameters:
|
976
|
+
#
|
977
|
+
# sourceFile - The source <FileName>.
|
978
|
+
# parsedFile - The parsed source file as an arrayref of <NaturalDocs::Parser::ParsedTopic> objects.
|
979
|
+
#
|
980
|
+
# Returns:
|
981
|
+
#
|
982
|
+
# The page content in HTML.
|
983
|
+
#
|
984
|
+
sub BuildContent #(sourceFile, parsedFile)
|
985
|
+
{
|
986
|
+
my ($self, $sourceFile, $parsedFile) = @_;
|
987
|
+
|
988
|
+
$self->ResetToolTips();
|
989
|
+
$imageAnchorNumber = 1;
|
990
|
+
$imageContent = undef;
|
991
|
+
|
992
|
+
my $output = '<div id=Content>';
|
993
|
+
my $i = 0;
|
994
|
+
|
995
|
+
while ($i < scalar @$parsedFile)
|
996
|
+
{
|
997
|
+
my $anchor = $self->SymbolToHTMLSymbol($parsedFile->[$i]->Symbol());
|
998
|
+
|
999
|
+
my $scope = NaturalDocs::Topics->TypeInfo($parsedFile->[$i]->Type())->Scope();
|
1000
|
+
|
1001
|
+
|
1002
|
+
# The anchors are closed, but not around the text, so the :hover CSS style won't accidentally kick in.
|
1003
|
+
|
1004
|
+
my $headerType;
|
1005
|
+
|
1006
|
+
if ($i == 0)
|
1007
|
+
{ $headerType = 'h1'; }
|
1008
|
+
elsif ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
1009
|
+
{ $headerType = 'h2'; }
|
1010
|
+
else
|
1011
|
+
{ $headerType = 'h3'; };
|
1012
|
+
|
1013
|
+
$output .=
|
1014
|
+
|
1015
|
+
'<div class="C' . NaturalDocs::Topics->NameOfType($parsedFile->[$i]->Type(), 0, 1) . '">'
|
1016
|
+
. '<div class=CTopic' . ($i == 0 ? ' id=MainTopic' : '') . '>'
|
1017
|
+
|
1018
|
+
. '<' . $headerType . ' class=CTitle>'
|
1019
|
+
. '<a name="' . $anchor . '"></a>'
|
1020
|
+
. $self->StringToHTML( $parsedFile->[$i]->Title(), ADD_HIDDEN_BREAKS)
|
1021
|
+
. '</' . $headerType . '>';
|
1022
|
+
|
1023
|
+
|
1024
|
+
my $hierarchy;
|
1025
|
+
if (NaturalDocs::Topics->TypeInfo( $parsedFile->[$i]->Type() )->ClassHierarchy())
|
1026
|
+
{
|
1027
|
+
$hierarchy = $self->BuildClassHierarchy($sourceFile, $parsedFile->[$i]->Symbol());
|
1028
|
+
};
|
1029
|
+
|
1030
|
+
my $summary;
|
1031
|
+
if ($i == 0 || $scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
1032
|
+
{
|
1033
|
+
$summary .= $self->BuildSummary($sourceFile, $parsedFile, $i);
|
1034
|
+
};
|
1035
|
+
|
1036
|
+
my $hasBody;
|
1037
|
+
if (defined $hierarchy || defined $summary ||
|
1038
|
+
defined $parsedFile->[$i]->Prototype() || defined $parsedFile->[$i]->Body())
|
1039
|
+
{
|
1040
|
+
$output .= '<div class=CBody>';
|
1041
|
+
$hasBody = 1;
|
1042
|
+
};
|
1043
|
+
|
1044
|
+
$output .= $hierarchy;
|
1045
|
+
|
1046
|
+
if (defined $parsedFile->[$i]->Prototype())
|
1047
|
+
{
|
1048
|
+
$output .= $self->BuildPrototype($parsedFile->[$i]->Type(), $parsedFile->[$i]->Prototype(), $sourceFile);
|
1049
|
+
};
|
1050
|
+
|
1051
|
+
if (defined $parsedFile->[$i]->Body())
|
1052
|
+
{
|
1053
|
+
$output .= $self->NDMarkupToHTML( $sourceFile, $parsedFile->[$i]->Body(), $parsedFile->[$i]->Symbol(),
|
1054
|
+
$parsedFile->[$i]->Package(), $parsedFile->[$i]->Type(),
|
1055
|
+
$parsedFile->[$i]->Using() );
|
1056
|
+
};
|
1057
|
+
|
1058
|
+
$output .= $summary;
|
1059
|
+
|
1060
|
+
|
1061
|
+
if ($hasBody)
|
1062
|
+
{ $output .= '</div>'; };
|
1063
|
+
|
1064
|
+
$output .=
|
1065
|
+
'</div>' # CTopic
|
1066
|
+
. '</div>' # CType
|
1067
|
+
. "\n\n";
|
1068
|
+
|
1069
|
+
$i++;
|
1070
|
+
};
|
1071
|
+
|
1072
|
+
$output .= '</div><!--Content-->';
|
1073
|
+
|
1074
|
+
return $output;
|
1075
|
+
};
|
1076
|
+
|
1077
|
+
|
1078
|
+
#
|
1079
|
+
# Function: BuildSummary
|
1080
|
+
#
|
1081
|
+
# Builds a summary, either for the entire file or the current class/section.
|
1082
|
+
#
|
1083
|
+
# Parameters:
|
1084
|
+
#
|
1085
|
+
# sourceFile - The source <FileName> the summary appears in.
|
1086
|
+
#
|
1087
|
+
# parsedFile - A reference to the parsed source file.
|
1088
|
+
#
|
1089
|
+
# index - The index into the parsed file to start at. If undef or zero, it builds a summary for the entire file. If it's the
|
1090
|
+
# index of a <TopicType> that starts or ends a scope, it builds a summary for that scope
|
1091
|
+
#
|
1092
|
+
# Returns:
|
1093
|
+
#
|
1094
|
+
# The summary in HTML.
|
1095
|
+
#
|
1096
|
+
sub BuildSummary #(sourceFile, parsedFile, index)
|
1097
|
+
{
|
1098
|
+
my ($self, $sourceFile, $parsedFile, $index) = @_;
|
1099
|
+
my $completeSummary;
|
1100
|
+
|
1101
|
+
if (!defined $index || $index == 0)
|
1102
|
+
{
|
1103
|
+
$index = 0;
|
1104
|
+
$completeSummary = 1;
|
1105
|
+
}
|
1106
|
+
else
|
1107
|
+
{
|
1108
|
+
# Skip the scope entry.
|
1109
|
+
$index++;
|
1110
|
+
};
|
1111
|
+
|
1112
|
+
if ($index + 1 >= scalar @$parsedFile)
|
1113
|
+
{ return undef; };
|
1114
|
+
|
1115
|
+
|
1116
|
+
my $scope = NaturalDocs::Topics->TypeInfo($parsedFile->[$index]->Type())->Scope();
|
1117
|
+
|
1118
|
+
# Return nothing if there's only one entry.
|
1119
|
+
if (!$completeSummary && ($scope == ::SCOPE_START() || $scope == ::SCOPE_END()) )
|
1120
|
+
{ return undef; };
|
1121
|
+
|
1122
|
+
|
1123
|
+
my $indent = 0;
|
1124
|
+
my $inGroup;
|
1125
|
+
|
1126
|
+
my $isMarked = 0;
|
1127
|
+
|
1128
|
+
my $output =
|
1129
|
+
'<!--START_ND_SUMMARY-->'
|
1130
|
+
. '<div class=Summary><div class=STitle>Summary</div>'
|
1131
|
+
|
1132
|
+
# Not all browsers get table padding right, so we need a div to apply the border.
|
1133
|
+
. '<div class=SBorder>'
|
1134
|
+
. '<table border=0 cellspacing=0 cellpadding=0 class=STable>';
|
1135
|
+
|
1136
|
+
while ($index < scalar @$parsedFile)
|
1137
|
+
{
|
1138
|
+
my $topic = $parsedFile->[$index];
|
1139
|
+
my $scope = NaturalDocs::Topics->TypeInfo($topic->Type())->Scope();
|
1140
|
+
|
1141
|
+
if (!$completeSummary && ($scope == ::SCOPE_START() || $scope == ::SCOPE_END()) )
|
1142
|
+
{ last; };
|
1143
|
+
|
1144
|
+
|
1145
|
+
# Remove modifiers as appropriate for the current entry.
|
1146
|
+
|
1147
|
+
if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
1148
|
+
{
|
1149
|
+
$indent = 0;
|
1150
|
+
$inGroup = 0;
|
1151
|
+
$isMarked = 0;
|
1152
|
+
}
|
1153
|
+
elsif ($topic->Type() eq ::TOPIC_GROUP())
|
1154
|
+
{
|
1155
|
+
if ($inGroup)
|
1156
|
+
{ $indent--; };
|
1157
|
+
|
1158
|
+
$inGroup = 0;
|
1159
|
+
$isMarked = 0;
|
1160
|
+
};
|
1161
|
+
|
1162
|
+
|
1163
|
+
$output .=
|
1164
|
+
'<tr class="S' . ($index == 0 ? 'Main' : NaturalDocs::Topics->NameOfType($topic->Type(), 0, 1))
|
1165
|
+
. ($indent ? ' SIndent' . $indent : '') . ($isMarked ? ' SMarked' : '') .'">'
|
1166
|
+
. '<td class=SEntry>';
|
1167
|
+
|
1168
|
+
# Add the entry itself.
|
1169
|
+
|
1170
|
+
my $toolTipProperties;
|
1171
|
+
|
1172
|
+
# We only want a tooltip here if there's a protoype. Otherwise it's redundant.
|
1173
|
+
|
1174
|
+
if (defined $topic->Prototype())
|
1175
|
+
{
|
1176
|
+
my $tooltipID = $self->BuildToolTip($topic->Symbol(), $sourceFile, $topic->Type(),
|
1177
|
+
$topic->Prototype(), $topic->Summary());
|
1178
|
+
$toolTipProperties = $self->BuildToolTipLinkProperties($tooltipID);
|
1179
|
+
};
|
1180
|
+
|
1181
|
+
$output .=
|
1182
|
+
'<a href="#' . $self->SymbolToHTMLSymbol($parsedFile->[$index]->Symbol()) . '" ' . $toolTipProperties . '>'
|
1183
|
+
. $self->StringToHTML( $parsedFile->[$index]->Title(), ADD_HIDDEN_BREAKS)
|
1184
|
+
. '</a>';
|
1185
|
+
|
1186
|
+
|
1187
|
+
$output .=
|
1188
|
+
'</td><td class=SDescription>';
|
1189
|
+
|
1190
|
+
if (defined $parsedFile->[$index]->Body())
|
1191
|
+
{
|
1192
|
+
$output .= $self->NDMarkupToHTML($sourceFile, $parsedFile->[$index]->Summary(),
|
1193
|
+
$parsedFile->[$index]->Symbol(), $parsedFile->[$index]->Package(),
|
1194
|
+
$parsedFile->[$index]->Type(), $parsedFile->[$index]->Using(),
|
1195
|
+
NDMARKUPTOHTML_SUMMARY);
|
1196
|
+
};
|
1197
|
+
|
1198
|
+
|
1199
|
+
$output .=
|
1200
|
+
'</td></tr>';
|
1201
|
+
|
1202
|
+
|
1203
|
+
# Prepare the modifiers for the next entry.
|
1204
|
+
|
1205
|
+
if ($scope == ::SCOPE_START() || $scope == ::SCOPE_END())
|
1206
|
+
{
|
1207
|
+
$indent = 1;
|
1208
|
+
$inGroup = 0;
|
1209
|
+
}
|
1210
|
+
elsif ($topic->Type() eq ::TOPIC_GROUP())
|
1211
|
+
{
|
1212
|
+
if (!$inGroup)
|
1213
|
+
{
|
1214
|
+
$indent++;
|
1215
|
+
$inGroup = 1;
|
1216
|
+
};
|
1217
|
+
};
|
1218
|
+
|
1219
|
+
$isMarked ^= 1;
|
1220
|
+
$index++;
|
1221
|
+
};
|
1222
|
+
|
1223
|
+
$output .=
|
1224
|
+
'</table>'
|
1225
|
+
. '</div>' # Body
|
1226
|
+
. '</div>' # Summary
|
1227
|
+
. "<!--END_ND_SUMMARY-->";
|
1228
|
+
|
1229
|
+
return $output;
|
1230
|
+
};
|
1231
|
+
|
1232
|
+
|
1233
|
+
#
|
1234
|
+
# Function: BuildPrototype
|
1235
|
+
#
|
1236
|
+
# Builds and returns the prototype as HTML.
|
1237
|
+
#
|
1238
|
+
# Parameters:
|
1239
|
+
#
|
1240
|
+
# type - The <TopicType> the prototype is from.
|
1241
|
+
# prototype - The prototype to format.
|
1242
|
+
# file - The <FileName> the prototype was defined in.
|
1243
|
+
#
|
1244
|
+
# Returns:
|
1245
|
+
#
|
1246
|
+
# The prototype in HTML.
|
1247
|
+
#
|
1248
|
+
sub BuildPrototype #(type, prototype, file)
|
1249
|
+
{
|
1250
|
+
my ($self, $type, $prototype, $file) = @_;
|
1251
|
+
|
1252
|
+
my $language = NaturalDocs::Languages->LanguageOf($file);
|
1253
|
+
my $prototypeObject = $language->ParsePrototype($type, $prototype);
|
1254
|
+
|
1255
|
+
my $output;
|
1256
|
+
|
1257
|
+
if ($prototypeObject->OnlyBeforeParameters())
|
1258
|
+
{
|
1259
|
+
$output =
|
1260
|
+
# A blockquote to scroll it if it's too long.
|
1261
|
+
'<blockquote>'
|
1262
|
+
# A surrounding table as a hack to make the div form-fit.
|
1263
|
+
. '<table border=0 cellspacing=0 cellpadding=0 class=Prototype><tr><td>'
|
1264
|
+
. $self->ConvertAmpChars($prototypeObject->BeforeParameters())
|
1265
|
+
. '</td></tr></table>'
|
1266
|
+
. '</blockquote>';
|
1267
|
+
}
|
1268
|
+
|
1269
|
+
else
|
1270
|
+
{
|
1271
|
+
my $params = $prototypeObject->Parameters();
|
1272
|
+
my $beforeParams = $prototypeObject->BeforeParameters();
|
1273
|
+
my $afterParams = $prototypeObject->AfterParameters();
|
1274
|
+
|
1275
|
+
|
1276
|
+
# Determine what features the prototype has and its length.
|
1277
|
+
|
1278
|
+
my ($hasType, $hasTypePrefix, $hasNamePrefix, $hasDefaultValue, $hasDefaultValuePrefix);
|
1279
|
+
my $maxParamLength = 0;
|
1280
|
+
|
1281
|
+
foreach my $param (@$params)
|
1282
|
+
{
|
1283
|
+
my $paramLength = length($param->Name());
|
1284
|
+
|
1285
|
+
if ($param->Type())
|
1286
|
+
{
|
1287
|
+
$hasType = 1;
|
1288
|
+
$paramLength += length($param->Type()) + 1;
|
1289
|
+
};
|
1290
|
+
if ($param->TypePrefix())
|
1291
|
+
{
|
1292
|
+
$hasTypePrefix = 1;
|
1293
|
+
$paramLength += length($param->TypePrefix()) + 1;
|
1294
|
+
};
|
1295
|
+
if ($param->NamePrefix())
|
1296
|
+
{
|
1297
|
+
$hasNamePrefix = 1;
|
1298
|
+
$paramLength += length($param->NamePrefix());
|
1299
|
+
};
|
1300
|
+
if ($param->DefaultValue())
|
1301
|
+
{
|
1302
|
+
$hasDefaultValue = 1;
|
1303
|
+
|
1304
|
+
# The length of the default value part is either the longest word, or 1/3 the total, whichever is longer. We do this
|
1305
|
+
# because we don't want parameter lines wrapping to more than three lines, and there's no guarantee that the line will
|
1306
|
+
# wrap at all. There's a small possibility that it could still wrap to four lines with this code, but we don't need to go
|
1307
|
+
# crazy(er) here.
|
1308
|
+
|
1309
|
+
my $thirdLength = length($param->DefaultValue()) / 3;
|
1310
|
+
|
1311
|
+
my @words = split(/ +/, $param->DefaultValue());
|
1312
|
+
my $maxWordLength = 0;
|
1313
|
+
|
1314
|
+
foreach my $word (@words)
|
1315
|
+
{
|
1316
|
+
if (length($word) > $maxWordLength)
|
1317
|
+
{ $maxWordLength = length($word); };
|
1318
|
+
};
|
1319
|
+
|
1320
|
+
$paramLength += ($maxWordLength > $thirdLength ? $maxWordLength : $thirdLength) + 1;
|
1321
|
+
};
|
1322
|
+
if ($param->DefaultValuePrefix())
|
1323
|
+
{
|
1324
|
+
$hasDefaultValuePrefix = 1;
|
1325
|
+
$paramLength += length($param->DefaultValuePrefix()) + 1;
|
1326
|
+
};
|
1327
|
+
|
1328
|
+
if ($paramLength > $maxParamLength)
|
1329
|
+
{ $maxParamLength = $paramLength; };
|
1330
|
+
};
|
1331
|
+
|
1332
|
+
my $useCondensed = (length($beforeParams) + $maxParamLength + length($afterParams) > 80 ? 1 : 0);
|
1333
|
+
my $parameterColumns = 1 + $hasType + $hasTypePrefix + $hasNamePrefix +
|
1334
|
+
$hasDefaultValue + $hasDefaultValuePrefix + $useCondensed;
|
1335
|
+
|
1336
|
+
$output =
|
1337
|
+
'<blockquote><table border=0 cellspacing=0 cellpadding=0 class=Prototype><tr><td>'
|
1338
|
+
|
1339
|
+
# Stupid hack to get it to work right in IE.
|
1340
|
+
. '<table border=0 cellspacing=0 cellpadding=0><tr>'
|
1341
|
+
|
1342
|
+
. '<td class=PBeforeParameters ' . ($useCondensed ? 'colspan=' . $parameterColumns : 'nowrap') . '>'
|
1343
|
+
. $self->ConvertAmpChars($beforeParams);
|
1344
|
+
|
1345
|
+
if ($beforeParams && $beforeParams !~ /[\(\[\{\<]$/)
|
1346
|
+
{ $output .= ' '; };
|
1347
|
+
|
1348
|
+
$output .=
|
1349
|
+
'</td>';
|
1350
|
+
|
1351
|
+
for (my $i = 0; $i < scalar @$params; $i++)
|
1352
|
+
{
|
1353
|
+
if ($useCondensed)
|
1354
|
+
{
|
1355
|
+
$output .= '</tr><tr><td> </td>';
|
1356
|
+
}
|
1357
|
+
elsif ($i > 0)
|
1358
|
+
{
|
1359
|
+
# Go to the next row and and skip the BeforeParameters cell.
|
1360
|
+
$output .= '</tr><tr><td></td>';
|
1361
|
+
};
|
1362
|
+
|
1363
|
+
if ($language->TypeBeforeParameter())
|
1364
|
+
{
|
1365
|
+
if ($hasTypePrefix)
|
1366
|
+
{
|
1367
|
+
my $htmlTypePrefix = $self->ConvertAmpChars($params->[$i]->TypePrefix());
|
1368
|
+
$htmlTypePrefix =~ s/ $/ /;
|
1369
|
+
|
1370
|
+
$output .=
|
1371
|
+
'<td class=PTypePrefix nowrap>'
|
1372
|
+
. $htmlTypePrefix
|
1373
|
+
. '</td>';
|
1374
|
+
};
|
1375
|
+
|
1376
|
+
if ($hasType)
|
1377
|
+
{
|
1378
|
+
$output .=
|
1379
|
+
'<td class=PType nowrap>'
|
1380
|
+
. $self->ConvertAmpChars($params->[$i]->Type()) . ' '
|
1381
|
+
. '</td>';
|
1382
|
+
};
|
1383
|
+
|
1384
|
+
if ($hasNamePrefix)
|
1385
|
+
{
|
1386
|
+
$output .=
|
1387
|
+
'<td class=PParameterPrefix nowrap>'
|
1388
|
+
. $self->ConvertAmpChars($params->[$i]->NamePrefix())
|
1389
|
+
. '</td>';
|
1390
|
+
};
|
1391
|
+
|
1392
|
+
$output .=
|
1393
|
+
'<td class=PParameter nowrap' . ($useCondensed && !$hasDefaultValue ? ' width=100%' : '') . '>'
|
1394
|
+
. $self->ConvertAmpChars($params->[$i]->Name())
|
1395
|
+
. '</td>';
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
else # !$language->TypeBeforeParameter()
|
1399
|
+
{
|
1400
|
+
$output .=
|
1401
|
+
'<td class=PParameter nowrap>'
|
1402
|
+
. $self->ConvertAmpChars( $params->[$i]->NamePrefix() . $params->[$i]->Name() )
|
1403
|
+
. '</td>';
|
1404
|
+
|
1405
|
+
if ($hasType || $hasTypePrefix)
|
1406
|
+
{
|
1407
|
+
my $typePrefix = $params->[$i]->TypePrefix();
|
1408
|
+
if ($typePrefix)
|
1409
|
+
{ $typePrefix .= ' '; };
|
1410
|
+
|
1411
|
+
$output .=
|
1412
|
+
'<td class=PType nowrap' . ($useCondensed && !$hasDefaultValue ? ' width=100%' : '') . '>'
|
1413
|
+
. ' ' . $self->ConvertAmpChars( $typePrefix . $params->[$i]->Type() )
|
1414
|
+
. '</td>';
|
1415
|
+
};
|
1416
|
+
};
|
1417
|
+
|
1418
|
+
if ($hasDefaultValuePrefix)
|
1419
|
+
{
|
1420
|
+
$output .=
|
1421
|
+
'<td class=PDefaultValuePrefix>'
|
1422
|
+
|
1423
|
+
. ' ' . $self->ConvertAmpChars( $params->[$i]->DefaultValuePrefix() ) . ' '
|
1424
|
+
. '</td>';
|
1425
|
+
};
|
1426
|
+
|
1427
|
+
if ($hasDefaultValue)
|
1428
|
+
{
|
1429
|
+
$output .=
|
1430
|
+
'<td class=PDefaultValue width=100%>'
|
1431
|
+
. ($hasDefaultValuePrefix ? '' : ' ') . $self->ConvertAmpChars( $params->[$i]->DefaultValue() )
|
1432
|
+
. '</td>';
|
1433
|
+
};
|
1434
|
+
};
|
1435
|
+
|
1436
|
+
if ($useCondensed)
|
1437
|
+
{ $output .= '</tr><tr>'; };
|
1438
|
+
|
1439
|
+
$output .=
|
1440
|
+
'<td class=PAfterParameters ' . ($useCondensed ? 'colspan=' . $parameterColumns : 'nowrap') . '>'
|
1441
|
+
. $self->ConvertAmpChars($afterParams);
|
1442
|
+
|
1443
|
+
if ($afterParams && $afterParams !~ /^[\)\]\}\>]/)
|
1444
|
+
{ $output .= ' '; };
|
1445
|
+
|
1446
|
+
$output .=
|
1447
|
+
'</td>'
|
1448
|
+
. '</tr></table>'
|
1449
|
+
|
1450
|
+
# Hack.
|
1451
|
+
. '</td></tr></table></blockquote>';
|
1452
|
+
};
|
1453
|
+
|
1454
|
+
return $output;
|
1455
|
+
};
|
1456
|
+
|
1457
|
+
|
1458
|
+
#
|
1459
|
+
# Function: BuildFooter
|
1460
|
+
#
|
1461
|
+
# Builds and returns the HTML footer for the page.
|
1462
|
+
#
|
1463
|
+
# Parameters:
|
1464
|
+
#
|
1465
|
+
# multiline - Whether it should be formatted on multiple lines or not.
|
1466
|
+
#
|
1467
|
+
# Dependencies:
|
1468
|
+
#
|
1469
|
+
# <Builder::HTML::UpdateFile()> and <Builder::HTML::UpdateIndex()> require this section to be surrounded with the exact
|
1470
|
+
# strings "<div id=Footer>" and "</div><!--Footer-->".
|
1471
|
+
#
|
1472
|
+
sub BuildFooter #(bool multiline)
|
1473
|
+
{
|
1474
|
+
my ($self, $multiline) = @_;
|
1475
|
+
|
1476
|
+
my $footer = NaturalDocs::Menu->Footer();
|
1477
|
+
my $timestamp = NaturalDocs::Menu->TimeStamp();
|
1478
|
+
my $divider;
|
1479
|
+
|
1480
|
+
if ($multiline)
|
1481
|
+
{ $divider = '</p><p>'; }
|
1482
|
+
else
|
1483
|
+
{ $divider = ' · '; };
|
1484
|
+
|
1485
|
+
|
1486
|
+
my $output = '<div id=Footer>';
|
1487
|
+
if ($multiline)
|
1488
|
+
{ $output .= '<p>'; };
|
1489
|
+
|
1490
|
+
if (defined $footer)
|
1491
|
+
{
|
1492
|
+
$footer =~ s/\(c\)/©/gi;
|
1493
|
+
$footer =~ s/\(tm\)/™/gi;
|
1494
|
+
$footer =~ s/\(r\)/®/gi;
|
1495
|
+
|
1496
|
+
$output .= $footer . $divider;
|
1497
|
+
};
|
1498
|
+
|
1499
|
+
if (defined $timestamp)
|
1500
|
+
{
|
1501
|
+
$output .= $timestamp . $divider;
|
1502
|
+
};
|
1503
|
+
|
1504
|
+
$output .=
|
1505
|
+
'<a href="' . NaturalDocs::Settings->AppURL() . '">'
|
1506
|
+
. 'Generated by Natural Docs'
|
1507
|
+
. '</a>';
|
1508
|
+
|
1509
|
+
if ($multiline)
|
1510
|
+
{ $output .= '</p>'; };
|
1511
|
+
|
1512
|
+
$output .=
|
1513
|
+
'</div><!--Footer-->';
|
1514
|
+
|
1515
|
+
return $output;
|
1516
|
+
};
|
1517
|
+
|
1518
|
+
|
1519
|
+
#
|
1520
|
+
# Function: BuildToolTip
|
1521
|
+
#
|
1522
|
+
# Builds the HTML for a symbol's tooltip and stores it in <tooltipHTML>.
|
1523
|
+
#
|
1524
|
+
# Parameters:
|
1525
|
+
#
|
1526
|
+
# symbol - The target <SymbolString>.
|
1527
|
+
# file - The <FileName> the target's defined in.
|
1528
|
+
# type - The symbol <TopicType>.
|
1529
|
+
# prototype - The target prototype, or undef for none.
|
1530
|
+
# summary - The target summary, or undef for none.
|
1531
|
+
#
|
1532
|
+
# Returns:
|
1533
|
+
#
|
1534
|
+
# If a tooltip is necessary for the link, returns the tooltip ID. If not, returns undef.
|
1535
|
+
#
|
1536
|
+
sub BuildToolTip #(symbol, file, type, prototype, summary)
|
1537
|
+
{
|
1538
|
+
my ($self, $symbol, $file, $type, $prototype, $summary) = @_;
|
1539
|
+
|
1540
|
+
if (defined $prototype || defined $summary)
|
1541
|
+
{
|
1542
|
+
my $htmlSymbol = $self->SymbolToHTMLSymbol($symbol);
|
1543
|
+
my $number = $tooltipSymbolsToNumbers{$htmlSymbol};
|
1544
|
+
|
1545
|
+
if (!defined $number)
|
1546
|
+
{
|
1547
|
+
$number = $tooltipNumber;
|
1548
|
+
$tooltipNumber++;
|
1549
|
+
|
1550
|
+
$tooltipSymbolsToNumbers{$htmlSymbol} = $number;
|
1551
|
+
|
1552
|
+
$tooltipHTML .=
|
1553
|
+
'<div class=CToolTip id="tt' . $number . '">'
|
1554
|
+
. '<div class=C' . NaturalDocs::Topics->NameOfType($type, 0, 1) . '>';
|
1555
|
+
|
1556
|
+
if (defined $prototype)
|
1557
|
+
{
|
1558
|
+
$tooltipHTML .= $self->BuildPrototype($type, $prototype, $file);
|
1559
|
+
};
|
1560
|
+
|
1561
|
+
if (defined $summary)
|
1562
|
+
{
|
1563
|
+
# The fact that we don't have scope or using shouldn't matter because links shouldn't be included in the style anyway.
|
1564
|
+
$summary = $self->NDMarkupToHTML($file, $summary, undef, undef, $type, undef, NDMARKUPTOHTML_TOOLTIP);
|
1565
|
+
$tooltipHTML .= $summary;
|
1566
|
+
};
|
1567
|
+
|
1568
|
+
$tooltipHTML .=
|
1569
|
+
'</div>'
|
1570
|
+
. '</div>';
|
1571
|
+
};
|
1572
|
+
|
1573
|
+
return 'tt' . $number;
|
1574
|
+
}
|
1575
|
+
else
|
1576
|
+
{ return undef; };
|
1577
|
+
};
|
1578
|
+
|
1579
|
+
#
|
1580
|
+
# Function: BuildToolTips
|
1581
|
+
#
|
1582
|
+
# Builds and returns the tooltips for the page in HTML.
|
1583
|
+
#
|
1584
|
+
sub BuildToolTips
|
1585
|
+
{
|
1586
|
+
my $self = shift;
|
1587
|
+
return "\n<!--START_ND_TOOLTIPS-->\n" . $tooltipHTML . "<!--END_ND_TOOLTIPS-->\n\n";
|
1588
|
+
};
|
1589
|
+
|
1590
|
+
#
|
1591
|
+
# Function: BuildClassHierarchy
|
1592
|
+
#
|
1593
|
+
# Builds and returns a class hierarchy diagram for the passed class, if applicable.
|
1594
|
+
#
|
1595
|
+
# Parameters:
|
1596
|
+
#
|
1597
|
+
# file - The source <FileName>.
|
1598
|
+
# class - The class <SymbolString> to build the hierarchy of.
|
1599
|
+
#
|
1600
|
+
sub BuildClassHierarchy #(file, symbol)
|
1601
|
+
{
|
1602
|
+
my ($self, $file, $symbol) = @_;
|
1603
|
+
|
1604
|
+
my @parents = NaturalDocs::ClassHierarchy->ParentsOf($symbol);
|
1605
|
+
@parents = sort { ::StringCompare($a, $b) } @parents;
|
1606
|
+
|
1607
|
+
my @children = NaturalDocs::ClassHierarchy->ChildrenOf($symbol);
|
1608
|
+
@children = sort { ::StringCompare($a, $b) } @children;
|
1609
|
+
|
1610
|
+
if (!scalar @parents && !scalar @children)
|
1611
|
+
{ return undef; };
|
1612
|
+
|
1613
|
+
my $output =
|
1614
|
+
'<div class=ClassHierarchy>';
|
1615
|
+
|
1616
|
+
if (scalar @parents)
|
1617
|
+
{
|
1618
|
+
$output .='<table border=0 cellspacing=0 cellpadding=0><tr><td>';
|
1619
|
+
|
1620
|
+
foreach my $parent (@parents)
|
1621
|
+
{
|
1622
|
+
$output .= $self->BuildClassHierarchyEntry($file, $parent, 'CHParent', 1);
|
1623
|
+
};
|
1624
|
+
|
1625
|
+
$output .= '</td></tr></table><div class=CHIndent>';
|
1626
|
+
};
|
1627
|
+
|
1628
|
+
$output .=
|
1629
|
+
'<table border=0 cellspacing=0 cellpadding=0><tr><td>'
|
1630
|
+
. $self->BuildClassHierarchyEntry($file, $symbol, 'CHCurrent', undef)
|
1631
|
+
. '</td></tr></table>';
|
1632
|
+
|
1633
|
+
if (scalar @children)
|
1634
|
+
{
|
1635
|
+
$output .=
|
1636
|
+
'<div class=CHIndent>'
|
1637
|
+
. '<table border=0 cellspacing=0 cellpadding=0><tr><td>';
|
1638
|
+
|
1639
|
+
if (scalar @children <= 5)
|
1640
|
+
{
|
1641
|
+
for (my $i = 0; $i < scalar @children; $i++)
|
1642
|
+
{ $output .= $self->BuildClassHierarchyEntry($file, $children[$i], 'CHChild', 1); };
|
1643
|
+
}
|
1644
|
+
else
|
1645
|
+
{
|
1646
|
+
for (my $i = 0; $i < 4; $i++)
|
1647
|
+
{ $output .= $self->BuildClassHierarchyEntry($file, $children[$i], 'CHChild', 1); };
|
1648
|
+
|
1649
|
+
$output .= '<div class=CHChildNote><div class=CHEntry>' . (scalar @children - 4) . ' other children</div></div>';
|
1650
|
+
};
|
1651
|
+
|
1652
|
+
$output .=
|
1653
|
+
'</td></tr></table>'
|
1654
|
+
. '</div>';
|
1655
|
+
};
|
1656
|
+
|
1657
|
+
if (scalar @parents)
|
1658
|
+
{ $output .= '</div>'; };
|
1659
|
+
|
1660
|
+
$output .=
|
1661
|
+
'</div>';
|
1662
|
+
|
1663
|
+
return $output;
|
1664
|
+
};
|
1665
|
+
|
1666
|
+
|
1667
|
+
#
|
1668
|
+
# Function: BuildClassHierarchyEntry
|
1669
|
+
#
|
1670
|
+
# Builds and returns a single class hierarchy entry.
|
1671
|
+
#
|
1672
|
+
# Parameters:
|
1673
|
+
#
|
1674
|
+
# file - The source <FileName>.
|
1675
|
+
# symbol - The class <SymbolString> whose entry is getting built.
|
1676
|
+
# style - The style to apply to the entry, such as <CHParent>.
|
1677
|
+
# link - Whether to build a link for this class or not. When building the selected class' entry, this should be false. It will
|
1678
|
+
# automatically handle whether the symbol is defined or not.
|
1679
|
+
#
|
1680
|
+
sub BuildClassHierarchyEntry #(file, symbol, style, link)
|
1681
|
+
{
|
1682
|
+
my ($self, $file, $symbol, $style, $link) = @_;
|
1683
|
+
|
1684
|
+
my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
|
1685
|
+
my $name = join(NaturalDocs::Languages->LanguageOf($file)->PackageSeparator(), @identifiers);
|
1686
|
+
$name = $self->StringToHTML($name);
|
1687
|
+
|
1688
|
+
my $output = '<div class=' . $style . '><div class=CHEntry>';
|
1689
|
+
|
1690
|
+
if ($link)
|
1691
|
+
{
|
1692
|
+
my $target = NaturalDocs::SymbolTable->Lookup($symbol, $file);
|
1693
|
+
|
1694
|
+
if (defined $target)
|
1695
|
+
{
|
1696
|
+
my $targetFile;
|
1697
|
+
|
1698
|
+
if ($target->File() ne $file)
|
1699
|
+
{ $targetFile = $self->MakeRelativeURL( $self->OutputFileOf($file), $self->OutputFileOf($target->File()), 1 ); };
|
1700
|
+
# else leave it undef
|
1701
|
+
|
1702
|
+
my $targetTooltipID = $self->BuildToolTip($symbol, $target->File(), $target->Type(),
|
1703
|
+
$target->Prototype(), $target->Summary());
|
1704
|
+
|
1705
|
+
my $toolTipProperties = $self->BuildToolTipLinkProperties($targetTooltipID);
|
1706
|
+
|
1707
|
+
$output .= '<a href="' . $targetFile . '#' . $self->SymbolToHTMLSymbol($symbol) . '" '
|
1708
|
+
. 'class=L' . NaturalDocs::Topics->NameOfType($target->Type(), 0, 1) . ' ' . $toolTipProperties . '>'
|
1709
|
+
. $name . '</a>';
|
1710
|
+
}
|
1711
|
+
else
|
1712
|
+
{ $output .= $name; };
|
1713
|
+
}
|
1714
|
+
else
|
1715
|
+
{ $output .= $name; };
|
1716
|
+
|
1717
|
+
$output .= '</div></div>';
|
1718
|
+
return $output;
|
1719
|
+
};
|
1720
|
+
|
1721
|
+
|
1722
|
+
#
|
1723
|
+
# Function: OpeningBrowserStyles
|
1724
|
+
#
|
1725
|
+
# Returns the JavaScript that will add opening browser styles if necessary.
|
1726
|
+
#
|
1727
|
+
sub OpeningBrowserStyles
|
1728
|
+
{
|
1729
|
+
my $self = shift;
|
1730
|
+
|
1731
|
+
return
|
1732
|
+
|
1733
|
+
'<script language=JavaScript><!--' . "\n"
|
1734
|
+
|
1735
|
+
# IE 4 and 5 don't understand 'undefined', so you can't say '!= undefined'.
|
1736
|
+
. 'if (browserType) {'
|
1737
|
+
. 'document.write("<div class=" + browserType + ">");'
|
1738
|
+
. 'if (browserVer) {'
|
1739
|
+
. 'document.write("<div class=" + browserVer + ">"); }'
|
1740
|
+
. '}'
|
1741
|
+
|
1742
|
+
. '// --></script>';
|
1743
|
+
};
|
1744
|
+
|
1745
|
+
|
1746
|
+
#
|
1747
|
+
# Function: ClosingBrowserStyles
|
1748
|
+
#
|
1749
|
+
# Returns the JavaScript that will close browser styles if necessary.
|
1750
|
+
#
|
1751
|
+
sub ClosingBrowserStyles
|
1752
|
+
{
|
1753
|
+
my $self = shift;
|
1754
|
+
|
1755
|
+
return
|
1756
|
+
|
1757
|
+
'<script language=JavaScript><!--' . "\n"
|
1758
|
+
|
1759
|
+
. 'if (browserType) {'
|
1760
|
+
. 'if (browserVer) {'
|
1761
|
+
. 'document.write("</div>"); }'
|
1762
|
+
. 'document.write("</div>");'
|
1763
|
+
. '}'
|
1764
|
+
|
1765
|
+
. '// --></script>';
|
1766
|
+
};
|
1767
|
+
|
1768
|
+
|
1769
|
+
#
|
1770
|
+
# Function: StandardComments
|
1771
|
+
#
|
1772
|
+
# Returns the standard HTML comments that should be included in every generated file. This includes <IEWebMark()>, so this
|
1773
|
+
# really is required for proper functionality.
|
1774
|
+
#
|
1775
|
+
sub StandardComments
|
1776
|
+
{
|
1777
|
+
my $self = shift;
|
1778
|
+
|
1779
|
+
return "\n\n"
|
1780
|
+
|
1781
|
+
. '<!-- Generated by Natural Docs, version ' . NaturalDocs::Settings->TextAppVersion() . ' -->' . "\n"
|
1782
|
+
. '<!-- ' . NaturalDocs::Settings->AppURL() . ' -->' . "\n\n"
|
1783
|
+
. $self->IEWebMark() . "\n\n";
|
1784
|
+
};
|
1785
|
+
|
1786
|
+
|
1787
|
+
#
|
1788
|
+
# Function: IEWebMark
|
1789
|
+
#
|
1790
|
+
# Returns the HTML comment necessary to get around the security warnings in IE starting with Windows XP Service Pack 2.
|
1791
|
+
#
|
1792
|
+
# With this mark, the HTML page is treated as if it were in the Internet security zone instead of the Local Machine zone. This
|
1793
|
+
# prevents the lockdown on scripting that causes an error message to appear with each page.
|
1794
|
+
#
|
1795
|
+
# More Information:
|
1796
|
+
#
|
1797
|
+
# - http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2brows.mspx#EHAA
|
1798
|
+
# - http://www.phdcc.com/xpsp2.htm#markoftheweb
|
1799
|
+
#
|
1800
|
+
sub IEWebMark
|
1801
|
+
{
|
1802
|
+
my $self = shift;
|
1803
|
+
|
1804
|
+
return '<!-- saved from url=(0026)http://www.naturaldocs.org -->';
|
1805
|
+
};
|
1806
|
+
|
1807
|
+
|
1808
|
+
|
1809
|
+
###############################################################################
|
1810
|
+
# Group: Index Functions
|
1811
|
+
|
1812
|
+
|
1813
|
+
#
|
1814
|
+
# Function: BuildIndexPages
|
1815
|
+
#
|
1816
|
+
# Builds an index file or files.
|
1817
|
+
#
|
1818
|
+
# Parameters:
|
1819
|
+
#
|
1820
|
+
# type - The <TopicType> the index is limited to, or undef for none.
|
1821
|
+
# indexSections - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement>
|
1822
|
+
# objects. The first section is for symbols, the second for numbers, and the rest for A through Z.
|
1823
|
+
# beginIndexPage - All the content of the HTML page up to where the index content should appear.
|
1824
|
+
# endIndexPage - All the content of the HTML page past where the index should appear.
|
1825
|
+
# beginSearchResultsPage - All the content of the HTML page up to where the search results content should appear.
|
1826
|
+
# endSearchResultsPage - All the content of the HTML page past where the search results content should appear.
|
1827
|
+
#
|
1828
|
+
# Returns:
|
1829
|
+
#
|
1830
|
+
# The number of pages in the index.
|
1831
|
+
#
|
1832
|
+
sub BuildIndexPages #(TopicType type, NaturalDocs::SymbolTable::IndexElement[] indexSections, string beginIndexPage, string endIndexPage, string beginSearchResultsPage, string endSearchResultsPage) => int
|
1833
|
+
{
|
1834
|
+
my ($self, $type, $indexSections, $beginIndexPage, $endIndexPage, $beginSearchResultsPage, $endSearchResultsPage) = @_;
|
1835
|
+
|
1836
|
+
|
1837
|
+
# Build the content.
|
1838
|
+
|
1839
|
+
my ($indexHTMLSections, $tooltipHTMLSections, $searchResultsHTMLSections) = $self->BuildIndexSections($indexSections);
|
1840
|
+
|
1841
|
+
|
1842
|
+
# Generate the search result pages.
|
1843
|
+
|
1844
|
+
for (my $i = 0; $i < 28; $i++)
|
1845
|
+
{
|
1846
|
+
if ($searchResultsHTMLSections->[$i])
|
1847
|
+
{
|
1848
|
+
my $searchResultsFileName = $self->SearchResultsFileOf($type, $searchExtensions[$i]);
|
1849
|
+
|
1850
|
+
open(INDEXFILEHANDLE, '>' . $searchResultsFileName)
|
1851
|
+
or die "Couldn't create output file " . $searchResultsFileName . ".\n";
|
1852
|
+
|
1853
|
+
print INDEXFILEHANDLE
|
1854
|
+
|
1855
|
+
$beginSearchResultsPage
|
1856
|
+
|
1857
|
+
. '<div class=SRStatus id=Loading>Loading...</div>'
|
1858
|
+
|
1859
|
+
. '<table border=0 cellspacing=0 cellpadding=0>'
|
1860
|
+
. $searchResultsHTMLSections->[$i]
|
1861
|
+
. '</table>'
|
1862
|
+
|
1863
|
+
. '<div class=SRStatus id=Searching>Searching...</div>'
|
1864
|
+
. '<div class=SRStatus id=NoMatches>No Matches</div>'
|
1865
|
+
|
1866
|
+
. '<script type="text/javascript"><!--' . "\n"
|
1867
|
+
. 'document.getElementById("Loading").style.display="none";' . "\n"
|
1868
|
+
. 'document.getElementById("NoMatches").style.display="none";' . "\n"
|
1869
|
+
|
1870
|
+
. 'var searchResults = new SearchResults("searchResults", "' . $self->CommandLineOption() . '");' . "\n"
|
1871
|
+
. 'searchResults.Search();' . "\n"
|
1872
|
+
. '--></script>'
|
1873
|
+
|
1874
|
+
. $endSearchResultsPage;
|
1875
|
+
|
1876
|
+
close(INDEXFILEHANDLE);
|
1877
|
+
};
|
1878
|
+
};
|
1879
|
+
|
1880
|
+
if (!$self->MadeEmptySearchResultsPage())
|
1881
|
+
{
|
1882
|
+
my $emptySearchResultsFileName = NaturalDocs::File->JoinPaths( $self->SearchResultsDirectory(), 'NoResults.html' );
|
1883
|
+
|
1884
|
+
open(INDEXFILEHANDLE, '>' . $emptySearchResultsFileName)
|
1885
|
+
or die "Couldn't create output file " . $emptySearchResultsFileName . ".\n";
|
1886
|
+
|
1887
|
+
print INDEXFILEHANDLE
|
1888
|
+
|
1889
|
+
$beginSearchResultsPage
|
1890
|
+
. '<div class=SRStatus id=NoMatches>No Matches</div>'
|
1891
|
+
. $endSearchResultsPage;
|
1892
|
+
|
1893
|
+
close(INDEXFILEHANDLE);
|
1894
|
+
|
1895
|
+
$self->SetMadeEmptySearchResultsPage(1);
|
1896
|
+
};
|
1897
|
+
|
1898
|
+
|
1899
|
+
# Generate the index pages.
|
1900
|
+
|
1901
|
+
my $page = 1;
|
1902
|
+
my $pageSize = 0;
|
1903
|
+
my @pageLocations;
|
1904
|
+
|
1905
|
+
# The maximum page size acceptable before starting a new page. Note that this doesn't include beginPage and endPage,
|
1906
|
+
# because we don't want something like a large menu screwing up the calculations.
|
1907
|
+
use constant PAGESIZE_LIMIT => 50000;
|
1908
|
+
|
1909
|
+
|
1910
|
+
# File the pages.
|
1911
|
+
|
1912
|
+
for (my $i = 0; $i < scalar @$indexHTMLSections; $i++)
|
1913
|
+
{
|
1914
|
+
if (!defined $indexHTMLSections->[$i])
|
1915
|
+
{ next; };
|
1916
|
+
|
1917
|
+
$pageSize += length($indexHTMLSections->[$i]) + length($tooltipHTMLSections->[$i]);
|
1918
|
+
$pageLocations[$i] = $page;
|
1919
|
+
|
1920
|
+
if ($pageSize + length($indexHTMLSections->[$i+1]) + length($tooltipHTMLSections->[$i+1]) > PAGESIZE_LIMIT)
|
1921
|
+
{
|
1922
|
+
$page++;
|
1923
|
+
$pageSize = 0;
|
1924
|
+
};
|
1925
|
+
};
|
1926
|
+
|
1927
|
+
|
1928
|
+
# Build the pages.
|
1929
|
+
|
1930
|
+
my $indexFileName;
|
1931
|
+
$page = -1;
|
1932
|
+
my $oldPage = -1;
|
1933
|
+
my $tooltips;
|
1934
|
+
my $firstHeading;
|
1935
|
+
|
1936
|
+
for (my $i = 0; $i < scalar @$indexHTMLSections; $i++)
|
1937
|
+
{
|
1938
|
+
if (!defined $indexHTMLSections->[$i])
|
1939
|
+
{ next; };
|
1940
|
+
|
1941
|
+
$page = $pageLocations[$i];
|
1942
|
+
|
1943
|
+
# Switch files if we need to.
|
1944
|
+
|
1945
|
+
if ($page != $oldPage)
|
1946
|
+
{
|
1947
|
+
if ($oldPage != -1)
|
1948
|
+
{
|
1949
|
+
print INDEXFILEHANDLE '</table>' . $tooltips . $endIndexPage;
|
1950
|
+
close(INDEXFILEHANDLE);
|
1951
|
+
$tooltips = undef;
|
1952
|
+
};
|
1953
|
+
|
1954
|
+
$indexFileName = $self->IndexFileOf($type, $page);
|
1955
|
+
|
1956
|
+
open(INDEXFILEHANDLE, '>' . $indexFileName)
|
1957
|
+
or die "Couldn't create output file " . $indexFileName . ".\n";
|
1958
|
+
|
1959
|
+
print INDEXFILEHANDLE $beginIndexPage . $self->BuildIndexNavigationBar($type, $page, \@pageLocations)
|
1960
|
+
. '<table border=0 cellspacing=0 cellpadding=0>';
|
1961
|
+
|
1962
|
+
$oldPage = $page;
|
1963
|
+
$firstHeading = 1;
|
1964
|
+
};
|
1965
|
+
|
1966
|
+
print INDEXFILEHANDLE
|
1967
|
+
'<tr>'
|
1968
|
+
. '<td class=IHeading' . ($firstHeading ? ' id=IFirstHeading' : '') . '>'
|
1969
|
+
. '<a name="' . $indexAnchors[$i] . '"></a>'
|
1970
|
+
. $indexHeadings[$i]
|
1971
|
+
. '</td>'
|
1972
|
+
. '<td></td>'
|
1973
|
+
. '</tr>'
|
1974
|
+
|
1975
|
+
. $indexHTMLSections->[$i];
|
1976
|
+
|
1977
|
+
$firstHeading = 0;
|
1978
|
+
$tooltips .= $tooltipHTMLSections->[$i];
|
1979
|
+
};
|
1980
|
+
|
1981
|
+
if ($page != -1)
|
1982
|
+
{
|
1983
|
+
print INDEXFILEHANDLE '</table>' . $tooltips . $endIndexPage;
|
1984
|
+
close(INDEXFILEHANDLE);
|
1985
|
+
}
|
1986
|
+
|
1987
|
+
# Build a dummy page so there's something at least.
|
1988
|
+
else
|
1989
|
+
{
|
1990
|
+
$indexFileName = $self->IndexFileOf($type, 1);
|
1991
|
+
|
1992
|
+
open(INDEXFILEHANDLE, '>' . $indexFileName)
|
1993
|
+
or die "Couldn't create output file " . $indexFileName . ".\n";
|
1994
|
+
|
1995
|
+
print INDEXFILEHANDLE
|
1996
|
+
$beginIndexPage
|
1997
|
+
. $self->BuildIndexNavigationBar($type, 1, \@pageLocations)
|
1998
|
+
. 'There are no entries in the ' . lc( NaturalDocs::Topics->NameOfType($type) ) . ' index.'
|
1999
|
+
. $endIndexPage;
|
2000
|
+
|
2001
|
+
close(INDEXFILEHANDLE);
|
2002
|
+
};
|
2003
|
+
|
2004
|
+
|
2005
|
+
return $page;
|
2006
|
+
};
|
2007
|
+
|
2008
|
+
|
2009
|
+
#
|
2010
|
+
# Function: BuildIndexSections
|
2011
|
+
#
|
2012
|
+
# Builds and returns the index and search results sections in HTML.
|
2013
|
+
#
|
2014
|
+
# Parameters:
|
2015
|
+
#
|
2016
|
+
# index - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement> objects.
|
2017
|
+
# The first section is for symbols, the second for numbers, and the rest for A through Z.
|
2018
|
+
#
|
2019
|
+
# Returns:
|
2020
|
+
#
|
2021
|
+
# The arrayref ( indexSections, tooltipSections, searchResultsSections ).
|
2022
|
+
#
|
2023
|
+
# Index 0 is the symbols, index 1 is the numbers, and each following index is A through Z. The content of each section
|
2024
|
+
# is its HTML, or undef if there is nothing for that section.
|
2025
|
+
#
|
2026
|
+
sub BuildIndexSections #(NaturalDocs::SymbolTable::IndexElement[] index) => ( string[], string[], string[] )
|
2027
|
+
{
|
2028
|
+
my ($self, $indexSections) = @_;
|
2029
|
+
|
2030
|
+
$self->ResetToolTips();
|
2031
|
+
%searchResultIDs = ( );
|
2032
|
+
|
2033
|
+
my $contentSections = [ ];
|
2034
|
+
my $tooltipSections = [ ];
|
2035
|
+
my $searchResultsSections = [ ];
|
2036
|
+
|
2037
|
+
for (my $section = 0; $section < scalar @$indexSections; $section++)
|
2038
|
+
{
|
2039
|
+
if (defined $indexSections->[$section])
|
2040
|
+
{
|
2041
|
+
my $total = scalar @{$indexSections->[$section]};
|
2042
|
+
|
2043
|
+
for (my $i = 0; $i < $total; $i++)
|
2044
|
+
{
|
2045
|
+
my $id;
|
2046
|
+
|
2047
|
+
if ($i == 0)
|
2048
|
+
{
|
2049
|
+
if ($total == 1)
|
2050
|
+
{ $id = 'IOnlySymbolPrefix'; }
|
2051
|
+
else
|
2052
|
+
{ $id = 'IFirstSymbolPrefix'; };
|
2053
|
+
}
|
2054
|
+
elsif ($i == $total - 1)
|
2055
|
+
{ $id = 'ILastSymbolPrefix'; };
|
2056
|
+
|
2057
|
+
my ($content, $searchResult) = $self->BuildIndexElement($indexSections->[$section]->[$i], $id);
|
2058
|
+
$contentSections->[$section] .= $content;
|
2059
|
+
$searchResultsSections->[$section] .= $searchResult;
|
2060
|
+
};
|
2061
|
+
|
2062
|
+
$tooltipSections->[$section] .= $self->BuildToolTips();
|
2063
|
+
$self->ResetToolTips(1);
|
2064
|
+
};
|
2065
|
+
};
|
2066
|
+
|
2067
|
+
|
2068
|
+
return ( $contentSections, $tooltipSections, $searchResultsSections );
|
2069
|
+
};
|
2070
|
+
|
2071
|
+
|
2072
|
+
#
|
2073
|
+
# Function: BuildIndexElement
|
2074
|
+
#
|
2075
|
+
# Converts a <NaturalDocs::SymbolTable::IndexElement> to HTML and returns it. It will handle all sub-elements automatically.
|
2076
|
+
#
|
2077
|
+
# Parameters:
|
2078
|
+
#
|
2079
|
+
# element - The <NaturalDocs::SymbolTable::IndexElement> to build.
|
2080
|
+
# cssID - The CSS ID to apply to the prefix.
|
2081
|
+
#
|
2082
|
+
# Recursion-Only Parameters:
|
2083
|
+
#
|
2084
|
+
# These parameters are used internally for recursion, and should not be set.
|
2085
|
+
#
|
2086
|
+
# symbol - If the element is below symbol level, the <SymbolString> to use.
|
2087
|
+
# package - If the element is below package level, the package <SymbolString> to use.
|
2088
|
+
# hasPackage - Whether the element is below package level. Is necessary because package may need to be undef.
|
2089
|
+
#
|
2090
|
+
# Returns:
|
2091
|
+
#
|
2092
|
+
# The array ( indexHTML, searchResultHTML ) which is the element in the respective HTML forms.
|
2093
|
+
#
|
2094
|
+
sub BuildIndexElement #(NaturalDocs::SymbolTable::IndexElement element, string cssID, SymbolString symbol, SymbolString package, bool hasPackage) => ( string, string )
|
2095
|
+
{
|
2096
|
+
my ($self, $element, $cssID, $symbol, $package, $hasPackage) = @_;
|
2097
|
+
|
2098
|
+
|
2099
|
+
# If we're doing a file sub-index entry...
|
2100
|
+
|
2101
|
+
if ($hasPackage)
|
2102
|
+
{
|
2103
|
+
my ($inputDirectory, $relativePath) = NaturalDocs::Settings->SplitFromInputDirectory($element->File());
|
2104
|
+
|
2105
|
+
return $self->BuildIndexLink($self->StringToHTML($relativePath, ADD_HIDDEN_BREAKS), $symbol,
|
2106
|
+
$package, $element->File(), $element->Type(),
|
2107
|
+
$element->Prototype(), $element->Summary(), 'IFile');
|
2108
|
+
}
|
2109
|
+
|
2110
|
+
|
2111
|
+
# If we're doing a package sub-index entry...
|
2112
|
+
|
2113
|
+
elsif (defined $symbol)
|
2114
|
+
|
2115
|
+
{
|
2116
|
+
my $text;
|
2117
|
+
|
2118
|
+
if ($element->Package())
|
2119
|
+
{
|
2120
|
+
$text = NaturalDocs::SymbolString->ToText($element->Package(), $element->PackageSeparator());
|
2121
|
+
$text = $self->StringToHTML($text, ADD_HIDDEN_BREAKS);
|
2122
|
+
}
|
2123
|
+
else
|
2124
|
+
{ $text = 'Global'; };
|
2125
|
+
|
2126
|
+
if (!$element->HasMultipleFiles())
|
2127
|
+
{
|
2128
|
+
return $self->BuildIndexLink($text, $symbol, $element->Package(), $element->File(), $element->Type(),
|
2129
|
+
$element->Prototype(), $element->Summary(), 'IParent');
|
2130
|
+
}
|
2131
|
+
|
2132
|
+
else
|
2133
|
+
{
|
2134
|
+
my $indexHTML =
|
2135
|
+
'<span class=IParent>'
|
2136
|
+
. $text
|
2137
|
+
. '</span>'
|
2138
|
+
. '<div class=ISubIndex>';
|
2139
|
+
|
2140
|
+
my $searchResultHTML = $indexHTML;
|
2141
|
+
|
2142
|
+
my $fileElements = $element->File();
|
2143
|
+
foreach my $fileElement (@$fileElements)
|
2144
|
+
{
|
2145
|
+
my ($i, $s) = $self->BuildIndexElement($fileElement, $cssID, $symbol, $element->Package(), 1);
|
2146
|
+
$indexHTML .= $i;
|
2147
|
+
$searchResultHTML .= $s;
|
2148
|
+
};
|
2149
|
+
|
2150
|
+
$indexHTML .= '</div>';
|
2151
|
+
$searchResultHTML .= '</div>';
|
2152
|
+
|
2153
|
+
return ($indexHTML, $searchResultHTML);
|
2154
|
+
};
|
2155
|
+
}
|
2156
|
+
|
2157
|
+
|
2158
|
+
# If we're doing a top-level symbol entry...
|
2159
|
+
|
2160
|
+
else
|
2161
|
+
{
|
2162
|
+
my $symbolText = $self->StringToHTML($element->SortableSymbol(), ADD_HIDDEN_BREAKS);
|
2163
|
+
my $symbolPrefix = $self->StringToHTML($element->IgnoredPrefix());
|
2164
|
+
my $searchResultID = $self->StringToSearchResultID($element->SortableSymbol());
|
2165
|
+
|
2166
|
+
my $indexHTML =
|
2167
|
+
'<tr>'
|
2168
|
+
. '<td class=ISymbolPrefix' . ($cssID ? ' id=' . $cssID : '') . '>'
|
2169
|
+
. ($symbolPrefix || ' ')
|
2170
|
+
. '</td><td class=IEntry>';
|
2171
|
+
|
2172
|
+
my $searchResultsHTML =
|
2173
|
+
'<div class=SRResult id=' . $searchResultID . '><div class=IEntry>';
|
2174
|
+
|
2175
|
+
if ($symbolPrefix)
|
2176
|
+
{ $searchResultsHTML .= '<span class=ISymbolPrefix>' . $symbolPrefix . '</span>'; };
|
2177
|
+
|
2178
|
+
if (!$element->HasMultiplePackages())
|
2179
|
+
{
|
2180
|
+
my $packageText;
|
2181
|
+
|
2182
|
+
if (defined $element->Package())
|
2183
|
+
{
|
2184
|
+
$packageText = NaturalDocs::SymbolString->ToText($element->Package(), $element->PackageSeparator());
|
2185
|
+
$packageText = $self->StringToHTML($packageText, ADD_HIDDEN_BREAKS);
|
2186
|
+
};
|
2187
|
+
|
2188
|
+
if (!$element->HasMultipleFiles())
|
2189
|
+
{
|
2190
|
+
my ($i, $s) =
|
2191
|
+
$self->BuildIndexLink($symbolText, $element->Symbol(), $element->Package(), $element->File(),
|
2192
|
+
$element->Type(), $element->Prototype(), $element->Summary(), 'ISymbol');
|
2193
|
+
$indexHTML .= $i;
|
2194
|
+
$searchResultsHTML .= $s;
|
2195
|
+
|
2196
|
+
if (defined $packageText)
|
2197
|
+
{
|
2198
|
+
$indexHTML .=
|
2199
|
+
', <span class=IParent>'
|
2200
|
+
. $packageText
|
2201
|
+
. '</span>';
|
2202
|
+
|
2203
|
+
$searchResultsHTML .=
|
2204
|
+
', <span class=IParent>'
|
2205
|
+
. $packageText
|
2206
|
+
. '</span>';
|
2207
|
+
};
|
2208
|
+
}
|
2209
|
+
else # hasMultipleFiles but not multiplePackages
|
2210
|
+
{
|
2211
|
+
$indexHTML .=
|
2212
|
+
'<span class=ISymbol>'
|
2213
|
+
. $symbolText
|
2214
|
+
. '</span>';
|
2215
|
+
|
2216
|
+
$searchResultsHTML .=
|
2217
|
+
q{<a href="javascript:searchResults.Toggle('} . $searchResultID . q{')" class=ISymbol>}
|
2218
|
+
. $symbolText
|
2219
|
+
. '</a>';
|
2220
|
+
|
2221
|
+
my $output;
|
2222
|
+
|
2223
|
+
if (defined $packageText)
|
2224
|
+
{
|
2225
|
+
$output .=
|
2226
|
+
', <span class=IParent>'
|
2227
|
+
. $packageText
|
2228
|
+
. '</span>';
|
2229
|
+
};
|
2230
|
+
|
2231
|
+
$output .=
|
2232
|
+
'<div class=ISubIndex>';
|
2233
|
+
|
2234
|
+
$indexHTML .= $output;
|
2235
|
+
$searchResultsHTML .= $output;
|
2236
|
+
|
2237
|
+
my $fileElements = $element->File();
|
2238
|
+
foreach my $fileElement (@$fileElements)
|
2239
|
+
{
|
2240
|
+
my ($i, $s) = $self->BuildIndexElement($fileElement, $cssID, $element->Symbol(), $element->Package(), 1);
|
2241
|
+
$indexHTML .= $i;
|
2242
|
+
$searchResultsHTML .= $s;
|
2243
|
+
};
|
2244
|
+
|
2245
|
+
$indexHTML .= '</div>';
|
2246
|
+
$searchResultsHTML .= '</div>';
|
2247
|
+
};
|
2248
|
+
}
|
2249
|
+
|
2250
|
+
else # hasMultiplePackages
|
2251
|
+
{
|
2252
|
+
$indexHTML .=
|
2253
|
+
'<span class=ISymbol>'
|
2254
|
+
. $symbolText
|
2255
|
+
. '</span>'
|
2256
|
+
. '<div class=ISubIndex>';
|
2257
|
+
|
2258
|
+
$searchResultsHTML .=
|
2259
|
+
q{<a href="javascript:searchResults.Toggle('} . $searchResultID . q{')" class=ISymbol>}
|
2260
|
+
. $symbolText
|
2261
|
+
. '</a>'
|
2262
|
+
. '<div class=ISubIndex>';
|
2263
|
+
|
2264
|
+
my $packageElements = $element->Package();
|
2265
|
+
foreach my $packageElement (@$packageElements)
|
2266
|
+
{
|
2267
|
+
my ($i, $s) = $self->BuildIndexElement($packageElement, $cssID, $element->Symbol());
|
2268
|
+
$indexHTML .= $i;
|
2269
|
+
$searchResultsHTML .= $s;
|
2270
|
+
};
|
2271
|
+
|
2272
|
+
$indexHTML .= '</div>';
|
2273
|
+
$searchResultsHTML .= '</div>';
|
2274
|
+
};
|
2275
|
+
|
2276
|
+
$indexHTML .= '</td></tr>';
|
2277
|
+
$searchResultsHTML .= '</div></div>';
|
2278
|
+
|
2279
|
+
return ($indexHTML, $searchResultsHTML);
|
2280
|
+
};
|
2281
|
+
};
|
2282
|
+
|
2283
|
+
|
2284
|
+
#
|
2285
|
+
# Function: BuildIndexLink
|
2286
|
+
#
|
2287
|
+
# Builds and returns the HTML associated with an index link. The HTML will be the a href tag, the text, and the closing tag.
|
2288
|
+
#
|
2289
|
+
# Parameters:
|
2290
|
+
#
|
2291
|
+
# text - The text of the link *in HTML*. Use <IndexSymbolToHTML()> if necessary.
|
2292
|
+
# symbol - The partial <SymbolString> to link to.
|
2293
|
+
# package - The package <SymbolString> of the symbol.
|
2294
|
+
# file - The <FileName> the symbol is defined in.
|
2295
|
+
# type - The <TopicType> of the symbol.
|
2296
|
+
# prototype - The prototype of the symbol, or undef if none.
|
2297
|
+
# summary - The summary of the symbol, or undef if none.
|
2298
|
+
# style - The CSS style to apply to the link.
|
2299
|
+
#
|
2300
|
+
# Returns:
|
2301
|
+
#
|
2302
|
+
# The array ( indexHTML, searchResultHTML ) which is the link in the respective forms.
|
2303
|
+
#
|
2304
|
+
sub BuildIndexLink #(string text, SymbolString symbol, SymbolString package, FileName file, TopicType type, string prototype, string summary, string style) => ( string, string )
|
2305
|
+
{
|
2306
|
+
my ($self, $text, $symbol, $package, $file, $type, $prototype, $summary, $style) = @_;
|
2307
|
+
|
2308
|
+
$symbol = NaturalDocs::SymbolString->Join($package, $symbol);
|
2309
|
+
|
2310
|
+
my $targetTooltipID = $self->BuildToolTip($symbol, $file, $type, $prototype, $summary);
|
2311
|
+
my $toolTipProperties = $self->BuildToolTipLinkProperties($targetTooltipID);
|
2312
|
+
|
2313
|
+
my $indexHTML = '<a href="' . $self->MakeRelativeURL( $self->IndexDirectory(), $self->OutputFileOf($file) )
|
2314
|
+
. '#' . $self->SymbolToHTMLSymbol($symbol) . '" ' . $toolTipProperties . ' '
|
2315
|
+
. 'class=' . $style . '>' . $text . '</a>';
|
2316
|
+
my $searchResultHTML = '<a href="' . $self->MakeRelativeURL( $self->SearchResultsDirectory(), $self->OutputFileOf($file) )
|
2317
|
+
. '#' . $self->SymbolToHTMLSymbol($symbol) . '" '
|
2318
|
+
. ($self->CommandLineOption eq 'HTML' ? 'target=_parent ' : '')
|
2319
|
+
. 'class=' . $style . '>' . $text . '</a>';
|
2320
|
+
|
2321
|
+
return ($indexHTML, $searchResultHTML);
|
2322
|
+
};
|
2323
|
+
|
2324
|
+
|
2325
|
+
#
|
2326
|
+
# Function: BuildIndexNavigationBar
|
2327
|
+
#
|
2328
|
+
# Builds a navigation bar for a page of the index.
|
2329
|
+
#
|
2330
|
+
# Parameters:
|
2331
|
+
#
|
2332
|
+
# type - The <TopicType> of the index, or undef for general.
|
2333
|
+
# page - The page of the index the navigation bar is for.
|
2334
|
+
# locations - An arrayref of the locations of each section. Index 0 is for the symbols, index 1 for the numbers, and the rest
|
2335
|
+
# for each letter. The values are the page numbers where the sections are located.
|
2336
|
+
#
|
2337
|
+
sub BuildIndexNavigationBar #(type, page, locations)
|
2338
|
+
{
|
2339
|
+
my ($self, $type, $page, $locations) = @_;
|
2340
|
+
|
2341
|
+
my $output = '<div class=INavigationBar>';
|
2342
|
+
|
2343
|
+
for (my $i = 0; $i < scalar @indexHeadings; $i++)
|
2344
|
+
{
|
2345
|
+
if ($i != 0)
|
2346
|
+
{ $output .= ' · '; };
|
2347
|
+
|
2348
|
+
if (defined $locations->[$i])
|
2349
|
+
{
|
2350
|
+
$output .= '<a href="';
|
2351
|
+
|
2352
|
+
if ($locations->[$i] != $page)
|
2353
|
+
{ $output .= $self->RelativeIndexFileOf($type, $locations->[$i]); };
|
2354
|
+
|
2355
|
+
$output .= '#' . $indexAnchors[$i] . '">' . $indexHeadings[$i] . '</a>';
|
2356
|
+
}
|
2357
|
+
else
|
2358
|
+
{
|
2359
|
+
$output .= $indexHeadings[$i];
|
2360
|
+
};
|
2361
|
+
};
|
2362
|
+
|
2363
|
+
$output .= '</div>';
|
2364
|
+
|
2365
|
+
return $output;
|
2366
|
+
};
|
2367
|
+
|
2368
|
+
|
2369
|
+
|
2370
|
+
###############################################################################
|
2371
|
+
# Group: File Functions
|
2372
|
+
|
2373
|
+
|
2374
|
+
#
|
2375
|
+
# Function: PurgeIndexFiles
|
2376
|
+
#
|
2377
|
+
# Removes all or some of the output files for an index.
|
2378
|
+
#
|
2379
|
+
# Parameters:
|
2380
|
+
#
|
2381
|
+
# type - The index <TopicType>.
|
2382
|
+
# indexSections - An arrayref of sections, each section being an arrayref <NaturalDocs::SymbolTable::IndexElement>
|
2383
|
+
# objects. The first section is for symbols, the second for numbers, and the rest for A through Z. May be
|
2384
|
+
# undef.
|
2385
|
+
# startingPage - If defined, only pages starting with this number will be removed. Otherwise all pages will be removed.
|
2386
|
+
#
|
2387
|
+
sub PurgeIndexFiles #(TopicType type, optional NaturalDocs::SymbolTable::IndexElement[] indexSections, optional int startingPage)
|
2388
|
+
{
|
2389
|
+
my ($self, $type, $indexSections, $page) = @_;
|
2390
|
+
|
2391
|
+
# First the regular index pages.
|
2392
|
+
|
2393
|
+
if (!defined $page)
|
2394
|
+
{ $page = 1; };
|
2395
|
+
|
2396
|
+
for (;;)
|
2397
|
+
{
|
2398
|
+
my $file = $self->IndexFileOf($type, $page);
|
2399
|
+
|
2400
|
+
if (-e $file)
|
2401
|
+
{
|
2402
|
+
unlink($file);
|
2403
|
+
$page++;
|
2404
|
+
}
|
2405
|
+
else
|
2406
|
+
{
|
2407
|
+
last;
|
2408
|
+
};
|
2409
|
+
};
|
2410
|
+
|
2411
|
+
|
2412
|
+
# Next the search results.
|
2413
|
+
|
2414
|
+
for (my $i = 0; $i < 28; $i++)
|
2415
|
+
{
|
2416
|
+
if (!$indexSections || !$indexSections->[$i])
|
2417
|
+
{
|
2418
|
+
my $file = $self->SearchResultsFileOf($type, $searchExtensions[$i]);
|
2419
|
+
|
2420
|
+
if (-e $file)
|
2421
|
+
{ unlink($file); };
|
2422
|
+
};
|
2423
|
+
};
|
2424
|
+
};
|
2425
|
+
|
2426
|
+
|
2427
|
+
#
|
2428
|
+
# Function: OutputFileOf
|
2429
|
+
#
|
2430
|
+
# Returns the output file name of the source file. Will be undef if it is not a file from a valid input directory.
|
2431
|
+
#
|
2432
|
+
sub OutputFileOf #(sourceFile)
|
2433
|
+
{
|
2434
|
+
my ($self, $sourceFile) = @_;
|
2435
|
+
|
2436
|
+
my ($inputDirectory, $relativeSourceFile) = NaturalDocs::Settings->SplitFromInputDirectory($sourceFile);
|
2437
|
+
if (!defined $inputDirectory)
|
2438
|
+
{ return undef; };
|
2439
|
+
|
2440
|
+
my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
|
2441
|
+
my $inputDirectoryName = NaturalDocs::Settings->InputDirectoryNameOf($inputDirectory);
|
2442
|
+
|
2443
|
+
$outputDirectory = NaturalDocs::File->JoinPaths( $outputDirectory,
|
2444
|
+
'files' . ($inputDirectoryName != 1 ? $inputDirectoryName : ''), 1 );
|
2445
|
+
|
2446
|
+
# We need to change any extensions to dashes because Apache will think file.pl.html is a script.
|
2447
|
+
# We also need to add a dash if the file doesn't have an extension so there'd be no conflicts with index.html,
|
2448
|
+
# FunctionIndex.html, etc.
|
2449
|
+
|
2450
|
+
if (!($relativeSourceFile =~ tr/./-/))
|
2451
|
+
{ $relativeSourceFile .= '-'; };
|
2452
|
+
|
2453
|
+
$relativeSourceFile =~ tr/ &?(){};/_/;
|
2454
|
+
$relativeSourceFile .= '.html';
|
2455
|
+
|
2456
|
+
return NaturalDocs::File->JoinPaths($outputDirectory, $relativeSourceFile);
|
2457
|
+
};
|
2458
|
+
|
2459
|
+
|
2460
|
+
#
|
2461
|
+
# Function: OutputImageOf
|
2462
|
+
#
|
2463
|
+
# Returns the output image file name of the source image file. Will be undef if it is not a file from a valid input directory.
|
2464
|
+
#
|
2465
|
+
sub OutputImageOf #(sourceImageFile)
|
2466
|
+
{
|
2467
|
+
my ($self, $sourceImageFile) = @_;
|
2468
|
+
|
2469
|
+
my $outputDirectory = NaturalDocs::Settings->OutputDirectoryOf($self);
|
2470
|
+
my $topLevelDirectory;
|
2471
|
+
|
2472
|
+
my ($inputDirectory, $relativeImageFile) = NaturalDocs::Settings->SplitFromInputDirectory($sourceImageFile);
|
2473
|
+
|
2474
|
+
if (defined $inputDirectory)
|
2475
|
+
{
|
2476
|
+
my $inputDirectoryName = NaturalDocs::Settings->InputDirectoryNameOf($inputDirectory);
|
2477
|
+
$topLevelDirectory = 'files' . ($inputDirectoryName != 1 ? $inputDirectoryName : '');
|
2478
|
+
}
|
2479
|
+
else
|
2480
|
+
{
|
2481
|
+
($inputDirectory, $relativeImageFile) = NaturalDocs::Settings->SplitFromImageDirectory($sourceImageFile);
|
2482
|
+
|
2483
|
+
if (!defined $inputDirectory)
|
2484
|
+
{ return undef; };
|
2485
|
+
|
2486
|
+
my $inputDirectoryName = NaturalDocs::Settings->ImageDirectoryNameOf($inputDirectory);
|
2487
|
+
$topLevelDirectory = 'images' . ($inputDirectoryName != 1 ? $inputDirectoryName : '');
|
2488
|
+
}
|
2489
|
+
|
2490
|
+
|
2491
|
+
$outputDirectory = NaturalDocs::File->JoinPaths($outputDirectory, $topLevelDirectory, 1);
|
2492
|
+
|
2493
|
+
$relativeImageFile =~ tr/ /_/;
|
2494
|
+
|
2495
|
+
return NaturalDocs::File->JoinPaths($outputDirectory, $relativeImageFile);
|
2496
|
+
};
|
2497
|
+
|
2498
|
+
|
2499
|
+
#
|
2500
|
+
# Function: IndexDirectory
|
2501
|
+
#
|
2502
|
+
# Returns the directory of the index files.
|
2503
|
+
#
|
2504
|
+
sub IndexDirectory
|
2505
|
+
{
|
2506
|
+
my $self = shift;
|
2507
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'index', 1);
|
2508
|
+
};
|
2509
|
+
|
2510
|
+
|
2511
|
+
#
|
2512
|
+
# Function: IndexFileOf
|
2513
|
+
#
|
2514
|
+
# Returns the output file name of the index file.
|
2515
|
+
#
|
2516
|
+
# Parameters:
|
2517
|
+
#
|
2518
|
+
# type - The <TopicType> of the index.
|
2519
|
+
# page - The page number. Undef is the same as one.
|
2520
|
+
#
|
2521
|
+
sub IndexFileOf #(type, page)
|
2522
|
+
{
|
2523
|
+
my ($self, $type, $page) = @_;
|
2524
|
+
return NaturalDocs::File->JoinPaths( $self->IndexDirectory(), $self->RelativeIndexFileOf($type, $page) );
|
2525
|
+
};
|
2526
|
+
|
2527
|
+
|
2528
|
+
#
|
2529
|
+
# Function: RelativeIndexFileOf
|
2530
|
+
#
|
2531
|
+
# Returns the output file name of the index file, relative to other index files.
|
2532
|
+
#
|
2533
|
+
# Parameters:
|
2534
|
+
#
|
2535
|
+
# type - The <TopicType> of the index.
|
2536
|
+
# page - The page number. Undef is the same as one.
|
2537
|
+
#
|
2538
|
+
sub RelativeIndexFileOf #(type, page)
|
2539
|
+
{
|
2540
|
+
my ($self, $type, $page) = @_;
|
2541
|
+
return NaturalDocs::Topics->NameOfType($type, 1, 1) . (defined $page && $page != 1 ? $page : '') . '.html';
|
2542
|
+
};
|
2543
|
+
|
2544
|
+
|
2545
|
+
#
|
2546
|
+
# Function: SearchResultsDirectory
|
2547
|
+
#
|
2548
|
+
# Returns the directory of the search results files.
|
2549
|
+
#
|
2550
|
+
sub SearchResultsDirectory
|
2551
|
+
{
|
2552
|
+
my $self = shift;
|
2553
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'search', 1);
|
2554
|
+
};
|
2555
|
+
|
2556
|
+
|
2557
|
+
#
|
2558
|
+
# Function: SearchResultsFileOf
|
2559
|
+
#
|
2560
|
+
# Returns the output file name of the search result file.
|
2561
|
+
#
|
2562
|
+
# Parameters:
|
2563
|
+
#
|
2564
|
+
# type - The <TopicType> of the index.
|
2565
|
+
# extra - The string to add to the end of the file name, such as "A" or "Symbols".
|
2566
|
+
#
|
2567
|
+
sub SearchResultsFileOf #(TopicType type, string extra)
|
2568
|
+
{
|
2569
|
+
my ($self, $type, $extra) = @_;
|
2570
|
+
|
2571
|
+
my $fileName = NaturalDocs::Topics->NameOfType($type, 1, 1) . $extra . '.html';
|
2572
|
+
|
2573
|
+
return NaturalDocs::File->JoinPaths( $self->SearchResultsDirectory(), $fileName );
|
2574
|
+
};
|
2575
|
+
|
2576
|
+
|
2577
|
+
#
|
2578
|
+
# Function: CSSDirectory
|
2579
|
+
#
|
2580
|
+
# Returns the directory of the CSS files.
|
2581
|
+
#
|
2582
|
+
sub CSSDirectory
|
2583
|
+
{
|
2584
|
+
my $self = shift;
|
2585
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'styles', 1);
|
2586
|
+
};
|
2587
|
+
|
2588
|
+
|
2589
|
+
#
|
2590
|
+
# Function: MainCSSFile
|
2591
|
+
#
|
2592
|
+
# Returns the location of the main CSS file.
|
2593
|
+
#
|
2594
|
+
sub MainCSSFile
|
2595
|
+
{
|
2596
|
+
my $self = shift;
|
2597
|
+
return NaturalDocs::File->JoinPaths( $self->CSSDirectory(), 'main.css' );
|
2598
|
+
};
|
2599
|
+
|
2600
|
+
|
2601
|
+
#
|
2602
|
+
# Function: JavaScriptDirectory
|
2603
|
+
#
|
2604
|
+
# Returns the directory of the JavaScript files.
|
2605
|
+
#
|
2606
|
+
sub JavaScriptDirectory
|
2607
|
+
{
|
2608
|
+
my $self = shift;
|
2609
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->OutputDirectoryOf($self), 'javascript', 1);
|
2610
|
+
};
|
2611
|
+
|
2612
|
+
|
2613
|
+
#
|
2614
|
+
# Function: MainJavaScriptFile
|
2615
|
+
#
|
2616
|
+
# Returns the location of the main JavaScript file.
|
2617
|
+
#
|
2618
|
+
sub MainJavaScriptFile
|
2619
|
+
{
|
2620
|
+
my $self = shift;
|
2621
|
+
return NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'main.js' );
|
2622
|
+
};
|
2623
|
+
|
2624
|
+
|
2625
|
+
#
|
2626
|
+
# Function: SearchDataJavaScriptFile
|
2627
|
+
#
|
2628
|
+
# Returns the location of the search data JavaScript file.
|
2629
|
+
#
|
2630
|
+
sub SearchDataJavaScriptFile
|
2631
|
+
{
|
2632
|
+
my $self = shift;
|
2633
|
+
return NaturalDocs::File->JoinPaths( $self->JavaScriptDirectory(), 'searchdata.js' );
|
2634
|
+
};
|
2635
|
+
|
2636
|
+
|
2637
|
+
|
2638
|
+
###############################################################################
|
2639
|
+
# Group: Support Functions
|
2640
|
+
|
2641
|
+
|
2642
|
+
#
|
2643
|
+
# Function: IndexTitleOf
|
2644
|
+
#
|
2645
|
+
# Returns the page title of the index file.
|
2646
|
+
#
|
2647
|
+
# Parameters:
|
2648
|
+
#
|
2649
|
+
# type - The type of index.
|
2650
|
+
#
|
2651
|
+
sub IndexTitleOf #(type)
|
2652
|
+
{
|
2653
|
+
my ($self, $type) = @_;
|
2654
|
+
|
2655
|
+
return ($type eq ::TOPIC_GENERAL() ? '' : NaturalDocs::Topics->NameOfType($type) . ' ') . 'Index';
|
2656
|
+
};
|
2657
|
+
|
2658
|
+
#
|
2659
|
+
# Function: MakeRelativeURL
|
2660
|
+
#
|
2661
|
+
# Returns a relative path between two files in the output tree and returns it in URL format.
|
2662
|
+
#
|
2663
|
+
# Parameters:
|
2664
|
+
#
|
2665
|
+
# baseFile - The base <FileName> in local format, *not* in URL format.
|
2666
|
+
# targetFile - The target <FileName> of the link in local format, *not* in URL format.
|
2667
|
+
# baseHasFileName - Whether baseFile has a file name attached or is just a path.
|
2668
|
+
#
|
2669
|
+
# Returns:
|
2670
|
+
#
|
2671
|
+
# The relative URL to the target.
|
2672
|
+
#
|
2673
|
+
sub MakeRelativeURL #(FileName baseFile, FileName targetFile, bool baseHasFileName) -> string relativeURL
|
2674
|
+
{
|
2675
|
+
my ($self, $baseFile, $targetFile, $baseHasFileName) = @_;
|
2676
|
+
|
2677
|
+
if ($baseHasFileName)
|
2678
|
+
{ $baseFile = NaturalDocs::File->NoFileName($baseFile) };
|
2679
|
+
|
2680
|
+
my $relativePath = NaturalDocs::File->MakeRelativePath($baseFile, $targetFile);
|
2681
|
+
|
2682
|
+
return $self->ConvertAmpChars( NaturalDocs::File->ConvertToURL($relativePath) );
|
2683
|
+
};
|
2684
|
+
|
2685
|
+
#
|
2686
|
+
# Function: StringToHTML
|
2687
|
+
#
|
2688
|
+
# Converts a text string to HTML. Does not apply paragraph tags or accept formatting tags.
|
2689
|
+
#
|
2690
|
+
# Parameters:
|
2691
|
+
#
|
2692
|
+
# string - The string to convert.
|
2693
|
+
# addHiddenBreaks - Whether to add hidden breaks to the string. You can use <ADD_HIDDEN_BREAKS> for this parameter
|
2694
|
+
# if you want to make the calling code clearer.
|
2695
|
+
#
|
2696
|
+
# Returns:
|
2697
|
+
#
|
2698
|
+
# The string in HTML.
|
2699
|
+
#
|
2700
|
+
sub StringToHTML #(string, addHiddenBreaks)
|
2701
|
+
{
|
2702
|
+
my ($self, $string, $addHiddenBreaks) = @_;
|
2703
|
+
|
2704
|
+
$string =~ s/&/&/g;
|
2705
|
+
$string =~ s/</</g;
|
2706
|
+
$string =~ s/>/>/g;
|
2707
|
+
|
2708
|
+
# Me likey the fancy quotes. They work in IE 4+, Mozilla, and Opera 5+. We've already abandoned NS4 with the CSS
|
2709
|
+
# styles, so might as well.
|
2710
|
+
$string =~ s/^\'/‘/gm;
|
2711
|
+
$string =~ s/([\ \(\[\{])\'/$1‘/g;
|
2712
|
+
$string =~ s/\'/’/g;
|
2713
|
+
|
2714
|
+
$string =~ s/^\"/“/gm;
|
2715
|
+
$string =~ s/([\ \(\[\{])\"/$1“/g;
|
2716
|
+
$string =~ s/\"/”/g;
|
2717
|
+
|
2718
|
+
# Me likey the double spaces too. As you can probably tell, I like print-formatting better than web-formatting. The indented
|
2719
|
+
# paragraphs without blank lines in between them do become readable when you have fancy quotes and double spaces too.
|
2720
|
+
$string = $self->AddDoubleSpaces($string);
|
2721
|
+
|
2722
|
+
if ($addHiddenBreaks)
|
2723
|
+
{ $string = $self->AddHiddenBreaks($string); };
|
2724
|
+
|
2725
|
+
return $string;
|
2726
|
+
};
|
2727
|
+
|
2728
|
+
|
2729
|
+
#
|
2730
|
+
# Function: SymbolToHTMLSymbol
|
2731
|
+
#
|
2732
|
+
# Converts a <SymbolString> to a HTML symbol, meaning one that is safe to include in anchor and link tags. You don't need
|
2733
|
+
# to pass the result to <ConvertAmpChars()>.
|
2734
|
+
#
|
2735
|
+
sub SymbolToHTMLSymbol #(symbol)
|
2736
|
+
{
|
2737
|
+
my ($self, $symbol) = @_;
|
2738
|
+
|
2739
|
+
my @identifiers = NaturalDocs::SymbolString->IdentifiersOf($symbol);
|
2740
|
+
my $htmlSymbol = join('.', @identifiers);
|
2741
|
+
|
2742
|
+
# If only Mozilla was nice about putting special characters in URLs like IE and Opera are, I could leave spaces in and replace
|
2743
|
+
# "<>& with their amp chars. But alas, Mozilla shows them as %20, etc. instead. It would have made for nice looking URLs.
|
2744
|
+
$htmlSymbol =~ tr/ \"<>\?&%/_/d;
|
2745
|
+
|
2746
|
+
return $htmlSymbol;
|
2747
|
+
};
|
2748
|
+
|
2749
|
+
|
2750
|
+
#
|
2751
|
+
# Function: StringToSearchResultID
|
2752
|
+
#
|
2753
|
+
# Takes a text string and translates it into something that can be used as a CSS ID.
|
2754
|
+
#
|
2755
|
+
# Parameters:
|
2756
|
+
#
|
2757
|
+
# string - The string to convert
|
2758
|
+
# dontIncrement - If set, it reuses the last generated ID. Otherwise it generates a new one if it matches a previously
|
2759
|
+
# generated one in a case-insensitive way.
|
2760
|
+
#
|
2761
|
+
sub StringToSearchResultID #(string string, bool dontIncrement = 0) => string
|
2762
|
+
{
|
2763
|
+
my ($self, $string, $dontIncrement) = @_;
|
2764
|
+
|
2765
|
+
$string =~ s/\_/_und/g;
|
2766
|
+
$string =~ s/ +/_spc/g;
|
2767
|
+
|
2768
|
+
my %translation = ( '~' => '_til', '!' => '_exc', '@' => '_att', '#' => '_num', '$' => '_dol', '%' => '_pct', '^' => '_car',
|
2769
|
+
'&' => '_amp', '*' => '_ast', '(' => '_lpa', ')' => '_rpa', '-' => '_min', '+' => '_plu', '=' => '_equ',
|
2770
|
+
'{' => '_lbc', '}' => '_rbc', '[' => '_lbk', ']' => '_rbk', ':' => '_col', ';' => '_sco', '"' => '_quo',
|
2771
|
+
'\'' => '_apo', '<' => '_lan', '>' => '_ran', ',' => '_com', '.' => '_per', '?' => '_que', '/' => '_sla' );
|
2772
|
+
|
2773
|
+
$string =~ s/([\~\!\@\#\$\%\^\&\*\(\)\-\+\=\{\}\[\]\:\;\"\'\<\>\,\.\?\/])/$translation{$1}/ge;
|
2774
|
+
$string =~ s/[^a-z0-9_]/_zzz/gi;
|
2775
|
+
|
2776
|
+
my $number = $searchResultIDs{lc($string)};
|
2777
|
+
|
2778
|
+
if (!$number)
|
2779
|
+
{ $number = 1; }
|
2780
|
+
elsif (!$dontIncrement)
|
2781
|
+
{ $number++; };
|
2782
|
+
|
2783
|
+
$searchResultIDs{lc($string)} = $number;
|
2784
|
+
|
2785
|
+
return 'SR' . ($number == 1 ? '' : $number) . '_' . $string;
|
2786
|
+
};
|
2787
|
+
|
2788
|
+
|
2789
|
+
#
|
2790
|
+
# Function: NDMarkupToHTML
|
2791
|
+
#
|
2792
|
+
# Converts a block of <NDMarkup> to HTML.
|
2793
|
+
#
|
2794
|
+
# Parameters:
|
2795
|
+
#
|
2796
|
+
# sourceFile - The source <FileName> the <NDMarkup> appears in.
|
2797
|
+
# text - The <NDMarkup> text to convert.
|
2798
|
+
# symbol - The topic <SymbolString> the <NDMarkup> appears in.
|
2799
|
+
# package - The package <SymbolString> the <NDMarkup> appears in.
|
2800
|
+
# type - The <TopicType> the <NDMarkup> appears in.
|
2801
|
+
# using - An arrayref of scope <SymbolStrings> the <NDMarkup> also has access to, or undef if none.
|
2802
|
+
# style - Set to one of the <NDMarkupToHTML Styles> or leave undef for general.
|
2803
|
+
#
|
2804
|
+
# Returns:
|
2805
|
+
#
|
2806
|
+
# The text in HTML.
|
2807
|
+
#
|
2808
|
+
sub NDMarkupToHTML #(sourceFile, text, symbol, package, type, using, style)
|
2809
|
+
{
|
2810
|
+
my ($self, $sourceFile, $text, $symbol, $package, $type, $using, $style) = @_;
|
2811
|
+
|
2812
|
+
my $dlSymbolBehavior;
|
2813
|
+
|
2814
|
+
if ($type == ::TOPIC_ENUMERATION())
|
2815
|
+
{ $dlSymbolBehavior = NaturalDocs::Languages->LanguageOf($sourceFile)->EnumValues(); }
|
2816
|
+
elsif (NaturalDocs::Topics->TypeInfo($type)->Scope() == ::SCOPE_ALWAYS_GLOBAL())
|
2817
|
+
{ $dlSymbolBehavior = ::ENUM_GLOBAL(); }
|
2818
|
+
else
|
2819
|
+
{ $dlSymbolBehavior = ::ENUM_UNDER_PARENT(); };
|
2820
|
+
|
2821
|
+
my $output;
|
2822
|
+
my $inCode;
|
2823
|
+
|
2824
|
+
my @splitText = split(/(<\/?code>)/, $text);
|
2825
|
+
|
2826
|
+
while (scalar @splitText)
|
2827
|
+
{
|
2828
|
+
$text = shift @splitText;
|
2829
|
+
|
2830
|
+
if ($text eq '<code>')
|
2831
|
+
{
|
2832
|
+
$output .= '<blockquote><pre>';
|
2833
|
+
$inCode = 1;
|
2834
|
+
}
|
2835
|
+
elsif ($text eq '</code>')
|
2836
|
+
{
|
2837
|
+
$output .= '</pre></blockquote>';
|
2838
|
+
$inCode = undef;
|
2839
|
+
}
|
2840
|
+
elsif ($inCode)
|
2841
|
+
{
|
2842
|
+
# Leave line breaks in.
|
2843
|
+
$output .= $text;
|
2844
|
+
}
|
2845
|
+
else
|
2846
|
+
{
|
2847
|
+
# Format non-code text.
|
2848
|
+
|
2849
|
+
# Convert linked images.
|
2850
|
+
if ($text =~ /<img mode=\"link\"/)
|
2851
|
+
{
|
2852
|
+
if ($style == NDMARKUPTOHTML_GENERAL)
|
2853
|
+
{
|
2854
|
+
# Split by tags we would want to see the linked images appear after. For example, an image link appearing in
|
2855
|
+
# the middle of a paragraph would appear after the end of that paragraph.
|
2856
|
+
my @imageBlocks = split(/(<p>.*?<\/p>|<dl>.*?<\/dl>|<ul>.*?<\/ul>)/, $text);
|
2857
|
+
$text = undef;
|
2858
|
+
|
2859
|
+
foreach my $imageBlock (@imageBlocks)
|
2860
|
+
{
|
2861
|
+
$imageBlock =~ s{<img mode=\"link\" target=\"([^\"]*)\" original=\"([^\"]*)\">}
|
2862
|
+
{$self->BuildImage($sourceFile, 'link', $1, $2)}ge;
|
2863
|
+
|
2864
|
+
$text .= $imageBlock . $imageContent;
|
2865
|
+
$imageContent = undef;
|
2866
|
+
};
|
2867
|
+
}
|
2868
|
+
|
2869
|
+
# Use only the text for tooltips and summaries.
|
2870
|
+
else
|
2871
|
+
{
|
2872
|
+
$text =~ s{<img mode=\"link\" target=\"[^\"]*\" original=\"([^\"]*)\">}{$1}g;
|
2873
|
+
};
|
2874
|
+
};
|
2875
|
+
|
2876
|
+
# Convert quotes to fancy quotes. This has to be done before links because some of them may have JavaScript
|
2877
|
+
# attributes that use the apostrophe character.
|
2878
|
+
$text =~ s/^\'/‘/gm;
|
2879
|
+
$text =~ s/([\ \(\[\{])\'/$1‘/g;
|
2880
|
+
$text =~ s/\'/’/g;
|
2881
|
+
|
2882
|
+
$text =~ s/^"/“/gm;
|
2883
|
+
$text =~ s/([\ \(\[\{])"/$1“/g;
|
2884
|
+
$text =~ s/"/”/g;
|
2885
|
+
|
2886
|
+
# Resolve and convert links, except for tooltips.
|
2887
|
+
if ($style != NDMARKUPTOHTML_TOOLTIP)
|
2888
|
+
{
|
2889
|
+
$text =~ s{<link target=\"([^\"]*)\" name=\"([^\"]*)\" original=\"([^\"]*)\">}
|
2890
|
+
{$self->BuildTextLink($1, $2, $3, $package, $using, $sourceFile)}ge;
|
2891
|
+
$text =~ s/<url target=\"([^\"]*)\" name=\"([^\"]*)\">/$self->BuildURLLink($1, $2)/ge;
|
2892
|
+
}
|
2893
|
+
else
|
2894
|
+
{
|
2895
|
+
$text =~ s{<link target=\"[^\"]*\" name=\"([^\"]*)\" original=\"[^\"]*\">}{$1}g;
|
2896
|
+
$text =~ s{<url target=\"[^\"]*\" name=\"([^\"]*)\">}{$1}g;
|
2897
|
+
};
|
2898
|
+
|
2899
|
+
# We do full e-mail links anyway just so the obfuscation remains.
|
2900
|
+
$text =~ s/<email target=\"([^\"]*)\" name=\"([^\"]*)\">/$self->BuildEMailLink($1, $2)/ge;
|
2901
|
+
|
2902
|
+
|
2903
|
+
# Convert inline images, but only for the general style.
|
2904
|
+
if ($style == NDMARKUPTOHTML_GENERAL)
|
2905
|
+
{
|
2906
|
+
$text =~ s{<img mode=\"inline\" target=\"([^\"]*)\" original=\"([^\"]*)\">}
|
2907
|
+
{$self->BuildImage($sourceFile, 'inline', $1, $2)}ge;
|
2908
|
+
}
|
2909
|
+
else
|
2910
|
+
{
|
2911
|
+
$text =~ s{<img mode=\"inline\" target=\"[^\"]*\" original=\"([^\"]*)\">}{$1}g;
|
2912
|
+
};
|
2913
|
+
|
2914
|
+
# Copyright symbols. Prevent conversion when part of (a), (b), (c) lists.
|
2915
|
+
if ($text !~ /\(a\)/i)
|
2916
|
+
{ $text =~ s/\(c\)/©/gi; };
|
2917
|
+
|
2918
|
+
# Trademark symbols.
|
2919
|
+
$text =~ s/\(tm\)/™/gi;
|
2920
|
+
$text =~ s/\(r\)/®/gi;
|
2921
|
+
|
2922
|
+
# Add double spaces too.
|
2923
|
+
$text = $self->AddDoubleSpaces($text);
|
2924
|
+
|
2925
|
+
# Headings
|
2926
|
+
$text =~ s/<h>/<h4 class=CHeading>/g;
|
2927
|
+
$text =~ s/<\/h>/<\/h4>/g;
|
2928
|
+
|
2929
|
+
# Description Lists
|
2930
|
+
$text =~ s/<dl>/<table border=0 cellspacing=0 cellpadding=0 class=CDescriptionList>/g;
|
2931
|
+
$text =~ s/<\/dl>/<\/table>/g;
|
2932
|
+
|
2933
|
+
$text =~ s/<de>/<tr><td class=CDLEntry>/g;
|
2934
|
+
$text =~ s/<\/de>/<\/td>/g;
|
2935
|
+
|
2936
|
+
if ($dlSymbolBehavior == ::ENUM_GLOBAL())
|
2937
|
+
{ $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol(undef, $1)/ge; }
|
2938
|
+
elsif ($dlSymbolBehavior == ::ENUM_UNDER_PARENT())
|
2939
|
+
{ $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol($package, $1)/ge; }
|
2940
|
+
else # ($dlSymbolBehavior == ::ENUM_UNDER_TYPE())
|
2941
|
+
{ $text =~ s/<ds>([^<]+)<\/ds>/$self->MakeDescriptionListSymbol($symbol, $1)/ge; }
|
2942
|
+
|
2943
|
+
sub MakeDescriptionListSymbol #(package, text)
|
2944
|
+
{
|
2945
|
+
my ($self, $package, $text) = @_;
|
2946
|
+
|
2947
|
+
$text = NaturalDocs::NDMarkup->RestoreAmpChars($text);
|
2948
|
+
my $symbol = NaturalDocs::SymbolString->FromText($text);
|
2949
|
+
|
2950
|
+
if (defined $package)
|
2951
|
+
{ $symbol = NaturalDocs::SymbolString->Join($package, $symbol); };
|
2952
|
+
|
2953
|
+
return
|
2954
|
+
'<tr>'
|
2955
|
+
. '<td class=CDLEntry>'
|
2956
|
+
# The anchors are closed, but not around the text, to prevent the :hover CSS style from kicking in.
|
2957
|
+
. '<a name="' . $self->SymbolToHTMLSymbol($symbol) . '"></a>'
|
2958
|
+
. $text
|
2959
|
+
. '</td>';
|
2960
|
+
};
|
2961
|
+
|
2962
|
+
$text =~ s/<dd>/<td class=CDLDescription>/g;
|
2963
|
+
$text =~ s/<\/dd>/<\/td><\/tr>/g;
|
2964
|
+
|
2965
|
+
$output .= $text;
|
2966
|
+
};
|
2967
|
+
};
|
2968
|
+
|
2969
|
+
return $output;
|
2970
|
+
};
|
2971
|
+
|
2972
|
+
|
2973
|
+
#
|
2974
|
+
# Function: BuildTextLink
|
2975
|
+
#
|
2976
|
+
# Creates a HTML link to a symbol, if it exists.
|
2977
|
+
#
|
2978
|
+
# Parameters:
|
2979
|
+
#
|
2980
|
+
# target - The link text.
|
2981
|
+
# name - The link name.
|
2982
|
+
# original - The original text as it appears in the source.
|
2983
|
+
# package - The package <SymbolString> the link appears in, or undef if none.
|
2984
|
+
# using - An arrayref of additional scope <SymbolStrings> the link has access to, or undef if none.
|
2985
|
+
# sourceFile - The <FileName> the link appears in.
|
2986
|
+
#
|
2987
|
+
# Target, name, and original are assumed to still have <NDMarkup> amp chars.
|
2988
|
+
#
|
2989
|
+
# Returns:
|
2990
|
+
#
|
2991
|
+
# The link in HTML, including tags. If the link doesn't resolve to anything, returns the HTML that should be substituted for it.
|
2992
|
+
#
|
2993
|
+
sub BuildTextLink #(target, name, original, package, using, sourceFile)
|
2994
|
+
{
|
2995
|
+
my ($self, $target, $name, $original, $package, $using, $sourceFile) = @_;
|
2996
|
+
|
2997
|
+
my $plainTarget = $self->RestoreAmpChars($target);
|
2998
|
+
|
2999
|
+
my $symbol = NaturalDocs::SymbolString->FromText($plainTarget);
|
3000
|
+
my $symbolTarget = NaturalDocs::SymbolTable->References(::REFERENCE_TEXT(), $symbol, $package, $using, $sourceFile);
|
3001
|
+
|
3002
|
+
if (defined $symbolTarget)
|
3003
|
+
{
|
3004
|
+
my $symbolTargetFile;
|
3005
|
+
|
3006
|
+
if ($symbolTarget->File() ne $sourceFile)
|
3007
|
+
{
|
3008
|
+
$symbolTargetFile = $self->MakeRelativeURL( $self->OutputFileOf($sourceFile),
|
3009
|
+
$self->OutputFileOf($symbolTarget->File()), 1 );
|
3010
|
+
};
|
3011
|
+
# else leave it undef
|
3012
|
+
|
3013
|
+
my $symbolTargetTooltipID = $self->BuildToolTip($symbolTarget->Symbol(), $sourceFile, $symbolTarget->Type(),
|
3014
|
+
$symbolTarget->Prototype(), $symbolTarget->Summary());
|
3015
|
+
|
3016
|
+
my $toolTipProperties = $self->BuildToolTipLinkProperties($symbolTargetTooltipID);
|
3017
|
+
|
3018
|
+
return '<a href="' . $symbolTargetFile . '#' . $self->SymbolToHTMLSymbol($symbolTarget->Symbol()) . '" '
|
3019
|
+
. 'class=L' . NaturalDocs::Topics->NameOfType($symbolTarget->Type(), 0, 1) . ' ' . $toolTipProperties . '>'
|
3020
|
+
. $name
|
3021
|
+
. '</a>';
|
3022
|
+
}
|
3023
|
+
else
|
3024
|
+
{
|
3025
|
+
return $original;
|
3026
|
+
};
|
3027
|
+
};
|
3028
|
+
|
3029
|
+
|
3030
|
+
#
|
3031
|
+
# Function: BuildURLLink
|
3032
|
+
#
|
3033
|
+
# Creates a HTML link to an external URL. Long URLs will have hidden breaks to allow them to wrap.
|
3034
|
+
#
|
3035
|
+
# Parameters:
|
3036
|
+
#
|
3037
|
+
# target - The URL to link to.
|
3038
|
+
# name - The label of the link.
|
3039
|
+
#
|
3040
|
+
# Both are assumed to still have <NDMarkup> amp chars.
|
3041
|
+
#
|
3042
|
+
# Returns:
|
3043
|
+
#
|
3044
|
+
# The HTML link, complete with tags.
|
3045
|
+
#
|
3046
|
+
sub BuildURLLink #(target, name)
|
3047
|
+
{
|
3048
|
+
my ($self, $target, $name) = @_;
|
3049
|
+
|
3050
|
+
# Don't restore amp chars on the target.
|
3051
|
+
|
3052
|
+
if (length $name < 50 || $name ne $target)
|
3053
|
+
{ return '<a href="' . $target . '" class=LURL target=_top>' . $name . '</a>'; };
|
3054
|
+
|
3055
|
+
my @segments = split(/([\,\/]|&)/, $target);
|
3056
|
+
my $output = '<a href="' . $target . '" class=LURL target=_top>';
|
3057
|
+
|
3058
|
+
# Get past the first batch of slashes, since we don't want to break on things like http://.
|
3059
|
+
|
3060
|
+
$output .= $segments[0];
|
3061
|
+
|
3062
|
+
my $i = 1;
|
3063
|
+
while ($i < scalar @segments && ($segments[$i] eq '/' || !$segments[$i]))
|
3064
|
+
{
|
3065
|
+
$output .= $segments[$i];
|
3066
|
+
$i++;
|
3067
|
+
};
|
3068
|
+
|
3069
|
+
# Now break on each one of those symbols.
|
3070
|
+
|
3071
|
+
while ($i < scalar @segments)
|
3072
|
+
{
|
3073
|
+
if ($segments[$i] eq ',' || $segments[$i] eq '/' || $segments[$i] eq '&')
|
3074
|
+
{ $output .= '<wbr>'; };
|
3075
|
+
|
3076
|
+
$output .= $segments[$i];
|
3077
|
+
$i++;
|
3078
|
+
};
|
3079
|
+
|
3080
|
+
$output .= '</a>';
|
3081
|
+
return $output;
|
3082
|
+
};
|
3083
|
+
|
3084
|
+
|
3085
|
+
#
|
3086
|
+
# Function: BuildEMailLink
|
3087
|
+
#
|
3088
|
+
# Creates a HTML link to an e-mail address. The address will be transparently munged to protect it (hopefully) from spambots.
|
3089
|
+
#
|
3090
|
+
# Parameters:
|
3091
|
+
#
|
3092
|
+
# target - The e-mail address.
|
3093
|
+
# name - The label of the link.
|
3094
|
+
#
|
3095
|
+
# Both are assumed to still have <NDMarkup> amp chars.
|
3096
|
+
#
|
3097
|
+
# Returns:
|
3098
|
+
#
|
3099
|
+
# The HTML e-mail link, complete with tags.
|
3100
|
+
#
|
3101
|
+
sub BuildEMailLink #(target, name)
|
3102
|
+
{
|
3103
|
+
my ($self, $target, $name) = @_;
|
3104
|
+
my @splitAddress;
|
3105
|
+
|
3106
|
+
|
3107
|
+
# Hack the address up. We want two user pieces and two host pieces.
|
3108
|
+
|
3109
|
+
my ($user, $host) = split(/\@/, $self->RestoreAmpChars($target));
|
3110
|
+
|
3111
|
+
my $userSplit = length($user) / 2;
|
3112
|
+
|
3113
|
+
push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($user, 0, $userSplit) );
|
3114
|
+
push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($user, $userSplit) );
|
3115
|
+
|
3116
|
+
push @splitAddress, '@';
|
3117
|
+
|
3118
|
+
my $hostSplit = length($host) / 2;
|
3119
|
+
|
3120
|
+
push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($host, 0, $hostSplit) );
|
3121
|
+
push @splitAddress, NaturalDocs::NDMarkup->ConvertAmpChars( substr($host, $hostSplit) );
|
3122
|
+
|
3123
|
+
|
3124
|
+
# Now put it back together again. We'll use spans to split the text transparently and JavaScript to split and join the link.
|
3125
|
+
|
3126
|
+
my $output =
|
3127
|
+
"<a href=\"#\" onClick=\"location.href='mai' + 'lto:' + '" . join("' + '", @splitAddress) . "'; return false;\" class=LEMail>";
|
3128
|
+
|
3129
|
+
if ($name eq $target)
|
3130
|
+
{
|
3131
|
+
$output .=
|
3132
|
+
$splitAddress[0] . '<span style="display: none">.nosp@m.</span>' . $splitAddress[1]
|
3133
|
+
. '<span>@</span>'
|
3134
|
+
. $splitAddress[3] . '<span style="display: none">.nosp@m.</span>' . $splitAddress[4];
|
3135
|
+
}
|
3136
|
+
else
|
3137
|
+
{ $output .= $name; };
|
3138
|
+
|
3139
|
+
$output .= '</a>';
|
3140
|
+
return $output;
|
3141
|
+
};
|
3142
|
+
|
3143
|
+
|
3144
|
+
#
|
3145
|
+
# Function: BuildImage
|
3146
|
+
#
|
3147
|
+
# Builds the HTML for an image.
|
3148
|
+
#
|
3149
|
+
# Parameters:
|
3150
|
+
#
|
3151
|
+
# sourceFile - The source <FileName> this image appears in.
|
3152
|
+
# mode - Either "inline" or "link".
|
3153
|
+
# target - The target.
|
3154
|
+
# original - The original text.
|
3155
|
+
#
|
3156
|
+
# All are assumed to still have <NDMarkup> amp chars.
|
3157
|
+
#
|
3158
|
+
# Returns:
|
3159
|
+
#
|
3160
|
+
# The result in HTML. If the mode was "link", the target image's HTML is added to <imageContent>.
|
3161
|
+
#
|
3162
|
+
sub BuildImage #(sourceFile, mode, target, original)
|
3163
|
+
{
|
3164
|
+
my ($self, $sourceFile, $mode, $target, $original) = @_;
|
3165
|
+
|
3166
|
+
my $targetNoAmp = $self->RestoreAmpChars($target);
|
3167
|
+
|
3168
|
+
my $image = NaturalDocs::ImageReferenceTable->GetReferenceTarget($sourceFile, $targetNoAmp);
|
3169
|
+
|
3170
|
+
if ($image)
|
3171
|
+
{
|
3172
|
+
my ($width, $height) = NaturalDocs::Project->ImageFileDimensions($image);
|
3173
|
+
|
3174
|
+
if ($mode eq 'inline')
|
3175
|
+
{
|
3176
|
+
return
|
3177
|
+
'<img src="' . $self->MakeRelativeURL($self->OutputFileOf($sourceFile),
|
3178
|
+
$self->OutputImageOf($image), 1) . '"'
|
3179
|
+
|
3180
|
+
. ($width && $height ? ' width="' . $width . '" height="' . $height . '"' : '')
|
3181
|
+
. '>';
|
3182
|
+
}
|
3183
|
+
else # link
|
3184
|
+
{
|
3185
|
+
# Make the text a little more friendly in the output by removing any folders and file extensions.
|
3186
|
+
# (see images/Table1.gif) will be turned into (see Table1).
|
3187
|
+
my $originalNoAmp = $self->RestoreAmpChars($original);
|
3188
|
+
my $targetIndex = index($originalNoAmp, $targetNoAmp);
|
3189
|
+
my ($shortTarget, $shortTargetNoAmp, $shortOriginal);
|
3190
|
+
|
3191
|
+
if ($targetIndex != -1)
|
3192
|
+
{
|
3193
|
+
$shortTargetNoAmp = (NaturalDocs::File->SplitPath($targetNoAmp))[2];
|
3194
|
+
$shortTargetNoAmp = NaturalDocs::File->NoExtension($shortTargetNoAmp);
|
3195
|
+
|
3196
|
+
substr($originalNoAmp, $targetIndex, length($targetNoAmp), $shortTargetNoAmp);
|
3197
|
+
|
3198
|
+
$shortOriginal = NaturalDocs::NDMarkup->ConvertAmpChars($originalNoAmp);
|
3199
|
+
$shortTarget = NaturalDocs::NDMarkup->ConvertAmpChars($shortTargetNoAmp);
|
3200
|
+
};
|
3201
|
+
|
3202
|
+
my $output =
|
3203
|
+
'<a href="#Image' . $imageAnchorNumber . '" class=CImageLink>'
|
3204
|
+
. ($shortOriginal || $original)
|
3205
|
+
. '</a>';
|
3206
|
+
|
3207
|
+
$imageContent .=
|
3208
|
+
'<blockquote>'
|
3209
|
+
. '<div class=CImage>'
|
3210
|
+
. '<a name="Image' . $imageAnchorNumber . '"></a>'
|
3211
|
+
. '<div class=CImageCaption>' . ($shortTarget || $target) . '</div>'
|
3212
|
+
. '<img src="' . $self->MakeRelativeURL($self->OutputFileOf($sourceFile),
|
3213
|
+
$self->OutputImageOf($image), 1) . '"'
|
3214
|
+
|
3215
|
+
. ($width && $height ? ' width="' . $width . '" height="' . $height . '"' : '')
|
3216
|
+
. '>'
|
3217
|
+
|
3218
|
+
. '</div></blockquote>';
|
3219
|
+
|
3220
|
+
$imageAnchorNumber++;
|
3221
|
+
return $output;
|
3222
|
+
};
|
3223
|
+
}
|
3224
|
+
else # !$image
|
3225
|
+
{
|
3226
|
+
if ($mode eq 'inline')
|
3227
|
+
{ return '<p>' . $original . '</p>'; }
|
3228
|
+
else #($mode eq 'link')
|
3229
|
+
{ return $original; };
|
3230
|
+
};
|
3231
|
+
};
|
3232
|
+
|
3233
|
+
|
3234
|
+
#
|
3235
|
+
# Function: BuildToolTipLinkProperties
|
3236
|
+
#
|
3237
|
+
# Returns the properties that should go in the link tag to add a tooltip to it. Because the function accepts undef, you can
|
3238
|
+
# call it without checking if <BuildToolTip()> returned undef or not.
|
3239
|
+
#
|
3240
|
+
# Parameters:
|
3241
|
+
#
|
3242
|
+
# toolTipID - The ID of the tooltip. If undef, the function will return undef.
|
3243
|
+
#
|
3244
|
+
# Returns:
|
3245
|
+
#
|
3246
|
+
# The properties that should be put in the link tag, or undef if toolTipID wasn't specified.
|
3247
|
+
#
|
3248
|
+
sub BuildToolTipLinkProperties #(toolTipID)
|
3249
|
+
{
|
3250
|
+
my ($self, $toolTipID) = @_;
|
3251
|
+
|
3252
|
+
if (defined $toolTipID)
|
3253
|
+
{
|
3254
|
+
my $currentNumber = $tooltipLinkNumber;
|
3255
|
+
$tooltipLinkNumber++;
|
3256
|
+
|
3257
|
+
return 'id=link' . $currentNumber . ' '
|
3258
|
+
. 'onMouseOver="ShowTip(event, \'' . $toolTipID . '\', \'link' . $currentNumber . '\')" '
|
3259
|
+
. 'onMouseOut="HideTip(\'' . $toolTipID . '\')"';
|
3260
|
+
}
|
3261
|
+
else
|
3262
|
+
{ return undef; };
|
3263
|
+
};
|
3264
|
+
|
3265
|
+
|
3266
|
+
#
|
3267
|
+
# Function: AddDoubleSpaces
|
3268
|
+
#
|
3269
|
+
# Adds second spaces after the appropriate punctuation with so they show up in HTML. They don't occur if there isn't at
|
3270
|
+
# least one space after the punctuation, so things like class.member notation won't be affected.
|
3271
|
+
#
|
3272
|
+
# Parameters:
|
3273
|
+
#
|
3274
|
+
# text - The text to convert.
|
3275
|
+
#
|
3276
|
+
# Returns:
|
3277
|
+
#
|
3278
|
+
# The text with double spaces as necessary.
|
3279
|
+
#
|
3280
|
+
sub AddDoubleSpaces #(text)
|
3281
|
+
{
|
3282
|
+
my ($self, $text) = @_;
|
3283
|
+
|
3284
|
+
# Question marks and exclamation points get double spaces unless followed by a lowercase letter.
|
3285
|
+
|
3286
|
+
$text =~ s/ ([^\ \t\r\n] [\!\?]) # Must appear after a non-whitespace character to apply.
|
3287
|
+
|
3288
|
+
("|&[lr][sd]quo;|[\'\"\]\}\)]?) # Tolerate closing quotes, parenthesis, etc.
|
3289
|
+
((?:<[^>]+>)*) # Tolerate tags
|
3290
|
+
|
3291
|
+
\ # The space
|
3292
|
+
(?![a-z]) # Not followed by a lowercase character.
|
3293
|
+
|
3294
|
+
/$1$2$3 \ /gx;
|
3295
|
+
|
3296
|
+
|
3297
|
+
# Periods get double spaces if it's not followed by a lowercase letter. However, if it's followed by a capital letter and the
|
3298
|
+
# preceding word is in the list of acceptable abbreviations, it won't get the double space. Yes, I do realize I am seriously
|
3299
|
+
# over-engineering this.
|
3300
|
+
|
3301
|
+
$text =~ s/ ([^\ \t\r\n]+) # The word prior to the period.
|
3302
|
+
|
3303
|
+
\.
|
3304
|
+
|
3305
|
+
("|&[lr][sd]quo;|[\'\"\]\}\)]?) # Tolerate closing quotes, parenthesis, etc.
|
3306
|
+
((?:<[^>]+>)*) # Tolerate tags
|
3307
|
+
|
3308
|
+
\ # The space
|
3309
|
+
([^a-z]) # The next character, if it's not a lowercase letter.
|
3310
|
+
|
3311
|
+
/$1 . '.' . $2 . $3 . MaybeExpand($1, $4) . $4/gex;
|
3312
|
+
|
3313
|
+
sub MaybeExpand #(leadWord, nextLetter)
|
3314
|
+
{
|
3315
|
+
my ($leadWord, $nextLetter) = @_;
|
3316
|
+
|
3317
|
+
if ($nextLetter =~ /^[A-Z]$/ && exists $abbreviations{ lc($leadWord) } )
|
3318
|
+
{ return ' '; }
|
3319
|
+
else
|
3320
|
+
{ return ' '; };
|
3321
|
+
};
|
3322
|
+
|
3323
|
+
return $text;
|
3324
|
+
};
|
3325
|
+
|
3326
|
+
|
3327
|
+
#
|
3328
|
+
# Function: ConvertAmpChars
|
3329
|
+
#
|
3330
|
+
# Converts certain characters to their HTML amp char equivalents.
|
3331
|
+
#
|
3332
|
+
# Parameters:
|
3333
|
+
#
|
3334
|
+
# text - The text to convert.
|
3335
|
+
#
|
3336
|
+
# Returns:
|
3337
|
+
#
|
3338
|
+
# The converted text.
|
3339
|
+
#
|
3340
|
+
sub ConvertAmpChars #(text)
|
3341
|
+
{
|
3342
|
+
my ($self, $text) = @_;
|
3343
|
+
|
3344
|
+
$text =~ s/&/&/g;
|
3345
|
+
$text =~ s/\"/"/g;
|
3346
|
+
$text =~ s/</</g;
|
3347
|
+
$text =~ s/>/>/g;
|
3348
|
+
|
3349
|
+
return $text;
|
3350
|
+
};
|
3351
|
+
|
3352
|
+
|
3353
|
+
#
|
3354
|
+
# Function: RestoreAmpChars
|
3355
|
+
#
|
3356
|
+
# Restores all amp characters to their original state. This works with both <NDMarkup> amp chars and fancy quotes.
|
3357
|
+
#
|
3358
|
+
# Parameters:
|
3359
|
+
#
|
3360
|
+
# text - The text to convert.
|
3361
|
+
#
|
3362
|
+
# Returns:
|
3363
|
+
#
|
3364
|
+
# The converted text.
|
3365
|
+
#
|
3366
|
+
sub RestoreAmpChars #(text)
|
3367
|
+
{
|
3368
|
+
my ($self, $text) = @_;
|
3369
|
+
|
3370
|
+
$text = NaturalDocs::NDMarkup->RestoreAmpChars($text);
|
3371
|
+
$text =~ s/&[lr]squo;/\'/g;
|
3372
|
+
$text =~ s/&[lr]dquo;/\"/g;
|
3373
|
+
|
3374
|
+
return $text;
|
3375
|
+
};
|
3376
|
+
|
3377
|
+
|
3378
|
+
#
|
3379
|
+
# Function: AddHiddenBreaks
|
3380
|
+
#
|
3381
|
+
# Adds hidden breaks to symbols. Puts them after symbol and directory separators so long names won't screw up the layout.
|
3382
|
+
#
|
3383
|
+
# Parameters:
|
3384
|
+
#
|
3385
|
+
# string - The string to break.
|
3386
|
+
#
|
3387
|
+
# Returns:
|
3388
|
+
#
|
3389
|
+
# The string with hidden breaks.
|
3390
|
+
#
|
3391
|
+
sub AddHiddenBreaks #(string)
|
3392
|
+
{
|
3393
|
+
my ($self, $string) = @_;
|
3394
|
+
|
3395
|
+
# \.(?=.{5,}) instead of \. so file extensions don't get breaks.
|
3396
|
+
# :+ instead of :: because Mac paths are separated by a : and we want to get those too.
|
3397
|
+
|
3398
|
+
$string =~ s/(\w(?:\.(?=.{5,})|:+|->|\\|\/))(\w)/$1 . '<wbr>' . $2/ge;
|
3399
|
+
|
3400
|
+
return $string;
|
3401
|
+
};
|
3402
|
+
|
3403
|
+
|
3404
|
+
#
|
3405
|
+
# Function: FindFirstFile
|
3406
|
+
#
|
3407
|
+
# A function that finds and returns the first file entry in the menu, or undef if none.
|
3408
|
+
#
|
3409
|
+
sub FindFirstFile
|
3410
|
+
{
|
3411
|
+
# Hidden parameter: arrayref
|
3412
|
+
# Used for recursion only.
|
3413
|
+
|
3414
|
+
my ($self, $arrayref) = @_;
|
3415
|
+
|
3416
|
+
if (!defined $arrayref)
|
3417
|
+
{ $arrayref = NaturalDocs::Menu->Content(); };
|
3418
|
+
|
3419
|
+
foreach my $entry (@$arrayref)
|
3420
|
+
{
|
3421
|
+
if ($entry->Type() == ::MENU_FILE())
|
3422
|
+
{
|
3423
|
+
return $entry;
|
3424
|
+
}
|
3425
|
+
elsif ($entry->Type() == ::MENU_GROUP())
|
3426
|
+
{
|
3427
|
+
my $result = $self->FindFirstFile($entry->GroupContent());
|
3428
|
+
if (defined $result)
|
3429
|
+
{ return $result; };
|
3430
|
+
};
|
3431
|
+
};
|
3432
|
+
|
3433
|
+
return undef;
|
3434
|
+
};
|
3435
|
+
|
3436
|
+
|
3437
|
+
#
|
3438
|
+
# Function: ExpandMenu
|
3439
|
+
#
|
3440
|
+
# Determines which groups should be expanded.
|
3441
|
+
#
|
3442
|
+
# Parameters:
|
3443
|
+
#
|
3444
|
+
# sourceFile - The source <FileName> to use if you're looking for a source file.
|
3445
|
+
# indexType - The index <TopicType> to use if you're looking for an index.
|
3446
|
+
# selectionHierarchy - The <FileName> the menu is being built for. Does not have to be on the menu itself.
|
3447
|
+
# rootLength - The length of the menu's root group, *not* including the contents of subgroups.
|
3448
|
+
#
|
3449
|
+
# Returns:
|
3450
|
+
#
|
3451
|
+
# An arrayref of all the group numbers that should be expanded. At minimum, it will contain the numbers of the groups
|
3452
|
+
# present in <menuSelectionHierarchy>, though it may contain more.
|
3453
|
+
#
|
3454
|
+
sub ExpandMenu #(FileName sourceFile, TopicType indexType, NaturalDocs::Menu::Entry[] selectionHierarchy, int rootLength) -> int[] groupsToExpand
|
3455
|
+
{
|
3456
|
+
my ($self, $sourceFile, $indexType, $menuSelectionHierarchy, $rootLength) = @_;
|
3457
|
+
|
3458
|
+
my $toExpand = [ ];
|
3459
|
+
|
3460
|
+
|
3461
|
+
# First expand everything in the selection hierarchy.
|
3462
|
+
|
3463
|
+
my $length = $rootLength;
|
3464
|
+
|
3465
|
+
foreach my $entry (@$menuSelectionHierarchy)
|
3466
|
+
{
|
3467
|
+
$length += $menuGroupLengths{$entry};
|
3468
|
+
push @$toExpand, $menuGroupNumbers{$entry};
|
3469
|
+
};
|
3470
|
+
|
3471
|
+
|
3472
|
+
# Now do multiple passes of group expansion as necessary. We start from bottomIndex and expand outwards. We stop going
|
3473
|
+
# in a direction if a group there is too long -- we do not skip over it and check later groups as well. However, if one direction
|
3474
|
+
# stops, the other can keep going.
|
3475
|
+
|
3476
|
+
my $pass = 1;
|
3477
|
+
my $hasSubGroups;
|
3478
|
+
|
3479
|
+
while ($length < MENU_LENGTH_LIMIT)
|
3480
|
+
{
|
3481
|
+
my $content;
|
3482
|
+
my $topIndex;
|
3483
|
+
my $bottomIndex;
|
3484
|
+
|
3485
|
+
|
3486
|
+
if ($pass == 1)
|
3487
|
+
{
|
3488
|
+
# First pass, we expand the selection's siblings.
|
3489
|
+
|
3490
|
+
if (scalar @$menuSelectionHierarchy)
|
3491
|
+
{ $content = $menuSelectionHierarchy->[0]->GroupContent(); }
|
3492
|
+
else
|
3493
|
+
{ $content = NaturalDocs::Menu->Content(); };
|
3494
|
+
|
3495
|
+
$bottomIndex = 0;
|
3496
|
+
|
3497
|
+
while ($bottomIndex < scalar @$content &&
|
3498
|
+
!($content->[$bottomIndex]->Type() == ::MENU_FILE() &&
|
3499
|
+
$content->[$bottomIndex]->Target() eq $sourceFile) &&
|
3500
|
+
!($content->[$bottomIndex]->Type() != ::MENU_INDEX() &&
|
3501
|
+
$content->[$bottomIndex]->Target() eq $indexType) )
|
3502
|
+
{ $bottomIndex++; };
|
3503
|
+
|
3504
|
+
if ($bottomIndex == scalar @$content)
|
3505
|
+
{ $bottomIndex = 0; };
|
3506
|
+
$topIndex = $bottomIndex - 1;
|
3507
|
+
}
|
3508
|
+
|
3509
|
+
elsif ($pass == 2)
|
3510
|
+
{
|
3511
|
+
# If the section we just expanded had no sub-groups, do another pass trying to expand the parent's sub-groups. The
|
3512
|
+
# net effect is that groups won't collapse as much unnecessarily. Someone can click on a file in a sub-group and the
|
3513
|
+
# groups in the parent will stay open.
|
3514
|
+
|
3515
|
+
if (!$hasSubGroups && scalar @$menuSelectionHierarchy)
|
3516
|
+
{
|
3517
|
+
if (scalar @$menuSelectionHierarchy > 1)
|
3518
|
+
{ $content = $menuSelectionHierarchy->[1]->GroupContent(); }
|
3519
|
+
else
|
3520
|
+
{ $content = NaturalDocs::Menu->Content(); };
|
3521
|
+
|
3522
|
+
$bottomIndex = 0;
|
3523
|
+
|
3524
|
+
while ($bottomIndex < scalar @$content &&
|
3525
|
+
$content->[$bottomIndex] != $menuSelectionHierarchy->[0])
|
3526
|
+
{ $bottomIndex++; };
|
3527
|
+
|
3528
|
+
$topIndex = $bottomIndex - 1;
|
3529
|
+
$bottomIndex++; # Increment past our own group.
|
3530
|
+
$hasSubGroups = undef;
|
3531
|
+
}
|
3532
|
+
else
|
3533
|
+
{ last; };
|
3534
|
+
}
|
3535
|
+
|
3536
|
+
# No more passes.
|
3537
|
+
else
|
3538
|
+
{ last; };
|
3539
|
+
|
3540
|
+
|
3541
|
+
while ( ($topIndex >= 0 || $bottomIndex < scalar @$content) && $length < MENU_LENGTH_LIMIT)
|
3542
|
+
{
|
3543
|
+
# We do the bottom first.
|
3544
|
+
|
3545
|
+
while ($bottomIndex < scalar @$content && $content->[$bottomIndex]->Type() != ::MENU_GROUP())
|
3546
|
+
{ $bottomIndex++; };
|
3547
|
+
|
3548
|
+
if ($bottomIndex < scalar @$content)
|
3549
|
+
{
|
3550
|
+
my $bottomEntry = $content->[$bottomIndex];
|
3551
|
+
$hasSubGroups = 1;
|
3552
|
+
|
3553
|
+
if ($length + $menuGroupLengths{$bottomEntry} <= MENU_LENGTH_LIMIT)
|
3554
|
+
{
|
3555
|
+
$length += $menuGroupLengths{$bottomEntry};
|
3556
|
+
push @$toExpand, $menuGroupNumbers{$bottomEntry};
|
3557
|
+
$bottomIndex++;
|
3558
|
+
}
|
3559
|
+
else
|
3560
|
+
{ $bottomIndex = scalar @$content; };
|
3561
|
+
};
|
3562
|
+
|
3563
|
+
# Top next.
|
3564
|
+
|
3565
|
+
while ($topIndex >= 0 && $content->[$topIndex]->Type() != ::MENU_GROUP())
|
3566
|
+
{ $topIndex--; };
|
3567
|
+
|
3568
|
+
if ($topIndex >= 0)
|
3569
|
+
{
|
3570
|
+
my $topEntry = $content->[$topIndex];
|
3571
|
+
$hasSubGroups = 1;
|
3572
|
+
|
3573
|
+
if ($length + $menuGroupLengths{$topEntry} <= MENU_LENGTH_LIMIT)
|
3574
|
+
{
|
3575
|
+
$length += $menuGroupLengths{$topEntry};
|
3576
|
+
push @$toExpand, $menuGroupNumbers{$topEntry};
|
3577
|
+
$topIndex--;
|
3578
|
+
}
|
3579
|
+
else
|
3580
|
+
{ $topIndex = -1; };
|
3581
|
+
};
|
3582
|
+
};
|
3583
|
+
|
3584
|
+
|
3585
|
+
$pass++;
|
3586
|
+
};
|
3587
|
+
|
3588
|
+
return $toExpand;
|
3589
|
+
};
|
3590
|
+
|
3591
|
+
|
3592
|
+
#
|
3593
|
+
# Function: GetMenuSelectionHierarchy
|
3594
|
+
#
|
3595
|
+
# Finds the sequence of menu groups that contain the current selection.
|
3596
|
+
#
|
3597
|
+
# Parameters:
|
3598
|
+
#
|
3599
|
+
# sourceFile - The source <FileName> to use if you're looking for a source file.
|
3600
|
+
# indexType - The index <TopicType> to use if you're looking for an index.
|
3601
|
+
#
|
3602
|
+
# Returns:
|
3603
|
+
#
|
3604
|
+
# An arrayref of the <NaturalDocs::Menu::Entry> objects of each group surrounding the selected menu item. First entry is the
|
3605
|
+
# group immediately encompassing it, and each subsequent entry works its way towards the outermost group.
|
3606
|
+
#
|
3607
|
+
sub GetMenuSelectionHierarchy #(FileName sourceFile, TopicType indexType) -> NaturalDocs::Menu::Entry[] selectionHierarchy
|
3608
|
+
{
|
3609
|
+
my ($self, $sourceFile, $indexType) = @_;
|
3610
|
+
|
3611
|
+
my $hierarchy = [ ];
|
3612
|
+
|
3613
|
+
$self->FindMenuSelection($sourceFile, $indexType, $hierarchy, NaturalDocs::Menu->Content());
|
3614
|
+
|
3615
|
+
return $hierarchy;
|
3616
|
+
};
|
3617
|
+
|
3618
|
+
|
3619
|
+
#
|
3620
|
+
# Function: FindMenuSelection
|
3621
|
+
#
|
3622
|
+
# A recursive function that deterimes if it or any of its sub-groups has the menu selection.
|
3623
|
+
#
|
3624
|
+
# Parameters:
|
3625
|
+
#
|
3626
|
+
# sourceFile - The source <FileName> to use if you're looking for a source file.
|
3627
|
+
# indexType - The index <TopicType> to use if you're looking for an index.
|
3628
|
+
# hierarchyRef - A reference to the menu selection hierarchy.
|
3629
|
+
# entries - An arrayref of <NaturalDocs::Menu::Entries> to search.
|
3630
|
+
#
|
3631
|
+
# Returns:
|
3632
|
+
#
|
3633
|
+
# Whether this group or any of its subgroups had the selection. If true, it will add any subgroups to the menu selection
|
3634
|
+
# hierarchy but not itself. This prevents the topmost entry from being added.
|
3635
|
+
#
|
3636
|
+
sub FindMenuSelection #(FileName sourceFile, TopicType indexType, NaturalDocs::Menu::Entry[] hierarchyRef, NaturalDocs::Menu::Entry[] entries) -> bool hasSelection
|
3637
|
+
{
|
3638
|
+
my ($self, $sourceFile, $indexType, $hierarchyRef, $entries) = @_;
|
3639
|
+
|
3640
|
+
foreach my $entry (@$entries)
|
3641
|
+
{
|
3642
|
+
if ($entry->Type() == ::MENU_GROUP())
|
3643
|
+
{
|
3644
|
+
# If the subgroup has the selection...
|
3645
|
+
if ( $self->FindMenuSelection($sourceFile, $indexType, $hierarchyRef, $entry->GroupContent()) )
|
3646
|
+
{
|
3647
|
+
push @$hierarchyRef, $entry;
|
3648
|
+
return 1;
|
3649
|
+
};
|
3650
|
+
}
|
3651
|
+
|
3652
|
+
elsif ($entry->Type() == ::MENU_FILE())
|
3653
|
+
{
|
3654
|
+
if ($sourceFile eq $entry->Target())
|
3655
|
+
{ return 1; };
|
3656
|
+
}
|
3657
|
+
|
3658
|
+
elsif ($entry->Type() == ::MENU_INDEX())
|
3659
|
+
{
|
3660
|
+
if ($indexType eq $entry->Target)
|
3661
|
+
{ return 1; };
|
3662
|
+
};
|
3663
|
+
};
|
3664
|
+
|
3665
|
+
return 0;
|
3666
|
+
};
|
3667
|
+
|
3668
|
+
|
3669
|
+
#
|
3670
|
+
# Function: ResetToolTips
|
3671
|
+
#
|
3672
|
+
# Resets the <ToolTip Package Variables> for a new page.
|
3673
|
+
#
|
3674
|
+
# Parameters:
|
3675
|
+
#
|
3676
|
+
# samePage - Set this flag if there's the possibility that the next batch of tooltips may be on the same page as the last.
|
3677
|
+
#
|
3678
|
+
sub ResetToolTips #(samePage)
|
3679
|
+
{
|
3680
|
+
my ($self, $samePage) = @_;
|
3681
|
+
|
3682
|
+
if (!$samePage)
|
3683
|
+
{
|
3684
|
+
$tooltipLinkNumber = 1;
|
3685
|
+
$tooltipNumber = 1;
|
3686
|
+
};
|
3687
|
+
|
3688
|
+
$tooltipHTML = undef;
|
3689
|
+
%tooltipSymbolsToNumbers = ( );
|
3690
|
+
};
|
3691
|
+
|
3692
|
+
|
3693
|
+
1;
|