bixbite 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/LICENSE +20 -0
  2. data/README.markdown +49 -0
  3. data/VERSION +1 -0
  4. data/bin/bixbite +73 -0
  5. data/lib/bixbite.rb +13 -0
  6. data/lib/bixbite/command.rb +14 -0
  7. data/lib/bixbite/create.rb +76 -0
  8. data/template/Rakefile +25 -0
  9. data/template/assets/bixbite/Rakefile.rb +297 -0
  10. data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
  11. data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
  12. data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
  13. data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
  14. data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
  15. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
  16. data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
  17. data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
  18. data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
  19. data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
  20. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
  21. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
  22. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
  23. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
  24. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
  25. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
  26. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
  27. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
  28. data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
  29. data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
  30. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
  31. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
  32. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
  33. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
  34. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
  35. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
  36. data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
  37. data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
  38. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
  39. data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
  40. data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
  41. data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
  42. data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
  43. data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
  44. data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
  45. data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
  46. data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
  47. data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
  48. data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
  49. data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
  50. data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
  51. data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
  52. data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
  53. data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
  54. data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
  55. data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
  56. data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
  57. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
  58. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
  59. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
  60. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
  61. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
  62. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
  63. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
  64. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
  65. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
  66. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
  67. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
  68. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
  69. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
  70. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
  71. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
  72. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
  73. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
  74. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
  75. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
  76. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
  77. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
  78. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
  79. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
  80. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
  81. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
  82. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
  83. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
  84. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
  85. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
  86. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
  87. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
  88. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
  89. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
  90. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
  91. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
  92. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
  93. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
  94. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
  95. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
  96. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
  97. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
  98. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
  99. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
  100. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
  101. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
  102. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
  103. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
  104. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
  105. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
  106. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
  107. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
  108. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
  109. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
  110. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
  111. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
  112. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
  113. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
  114. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
  115. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
  116. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
  117. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
  118. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
  119. data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
  120. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
  121. data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
  122. data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
  123. data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
  124. data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
  125. data/template/assets/utilities/pngout +0 -0
  126. data/template/deploy/public_html/.htaccess +0 -0
  127. data/template/documentation/js/.htaccess +0 -0
  128. data/template/src/html/.htaccess +76 -0
  129. data/template/src/html/css/cmn/global.css +96 -0
  130. data/template/src/html/css/cmn/ie.css +15 -0
  131. data/template/src/html/css/cmn/ie6.css +15 -0
  132. data/template/src/html/images/cmn/.htaccess +0 -0
  133. data/template/src/html/images/tmp/.htaccess +0 -0
  134. data/template/src/html/includes/debug.inc +5 -0
  135. data/template/src/html/includes/footer.inc +52 -0
  136. data/template/src/html/includes/header.inc +61 -0
  137. data/template/src/html/includes/html.inc +3 -0
  138. data/template/src/html/includes/namespace.inc +19 -0
  139. data/template/src/html/includes/page.inc +151 -0
  140. data/template/src/html/index.html +35 -0
  141. data/template/src/html/js/cmn/bootstrap.js +74 -0
  142. data/template/src/html/js/cmn/global.js +142 -0
  143. data/template/src/html/js/cmn/lib/LAB.js +348 -0
  144. data/template/src/html/min/.htaccess +4 -0
  145. data/template/src/html/min/MinifyCLI.php +19 -0
  146. data/template/src/html/min/README.txt +132 -0
  147. data/template/src/html/min/builder/_index.js +242 -0
  148. data/template/src/html/min/builder/bm.js +36 -0
  149. data/template/src/html/min/builder/index.php +182 -0
  150. data/template/src/html/min/builder/ocCheck.php +36 -0
  151. data/template/src/html/min/builder/rewriteTest.js +1 -0
  152. data/template/src/html/min/config.php +187 -0
  153. data/template/src/html/min/groupsConfig.php +34 -0
  154. data/template/src/html/min/index.php +66 -0
  155. data/template/src/html/min/lib/FirePHP.php +1370 -0
  156. data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
  157. data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
  158. data/template/src/html/min/lib/JSMin.php +314 -0
  159. data/template/src/html/min/lib/JSMinPlus.php +1872 -0
  160. data/template/src/html/min/lib/Minify.php +532 -0
  161. data/template/src/html/min/lib/Minify/Build.php +103 -0
  162. data/template/src/html/min/lib/Minify/CSS.php +83 -0
  163. data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
  164. data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
  165. data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
  166. data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
  167. data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
  168. data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
  169. data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
  170. data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
  171. data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
  172. data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
  173. data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
  174. data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
  175. data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
  176. data/template/src/html/min/lib/Minify/HTML.php +245 -0
  177. data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
  178. data/template/src/html/min/lib/Minify/Lines.php +131 -0
  179. data/template/src/html/min/lib/Minify/Logger.php +45 -0
  180. data/template/src/html/min/lib/Minify/Packer.php +37 -0
  181. data/template/src/html/min/lib/Minify/Source.php +187 -0
  182. data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
  183. data/template/src/html/min/lib/Solar/Dir.php +199 -0
  184. data/template/src/html/min/lib/closure-compiler.jar +0 -0
  185. data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
  186. data/template/src/html/min/utils.php +90 -0
  187. data/template/src/templates/css/template.css +7 -0
  188. data/template/src/templates/js/template.js +72 -0
  189. data/template/src/templates/template.html +18 -0
  190. data/template/src/yaml/config.yml +46 -0
  191. data/template/src/yaml/deploy.yml +35 -0
  192. data/test/bixbite_test.rb +7 -0
  193. data/test/test_helper.rb +10 -0
  194. metadata +278 -0
@@ -0,0 +1,540 @@
1
+ ###############################################################################
2
+ #
3
+ # Package: NaturalDocs::File
4
+ #
5
+ ###############################################################################
6
+ #
7
+ # A package to manage file access across platforms. Incorporates functions from various standard File:: packages, but more
8
+ # importantly, works around the glorious suckage present in File::Spec, at least in version 0.82 and earlier. Read the "Why oh
9
+ # why?" sections for why this package was necessary.
10
+ #
11
+ # Usage and Dependencies:
12
+ #
13
+ # - The package doesn't depend on any other Natural Docs packages and is ready to use immediately.
14
+ #
15
+ # - All functions except <CanonizePath()> assume that all parameters are canonized.
16
+ #
17
+ ###############################################################################
18
+
19
+ # This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
20
+ # Natural Docs is licensed under the GPL
21
+
22
+ use File::Spec ();
23
+ use File::Path ();
24
+ use File::Copy ();
25
+
26
+ use strict;
27
+ use integer;
28
+
29
+ package NaturalDocs::File;
30
+
31
+
32
+ #
33
+ # Function: CheckCompatibility
34
+ #
35
+ # Checks if the standard packages required by this one are up to snuff and dies if they aren't. This is done because I can't
36
+ # tell which versions of File::Spec have splitpath just by the version numbers.
37
+ #
38
+ sub CheckCompatibility
39
+ {
40
+ my ($self) = @_;
41
+
42
+ eval {
43
+ File::Spec->splitpath('');
44
+ };
45
+
46
+ if ($@)
47
+ {
48
+ NaturalDocs::Error->SoftDeath("Natural Docs requires a newer version of File::Spec than you have. "
49
+ . "You must either upgrade it or upgrade Perl.");
50
+ };
51
+ };
52
+
53
+
54
+ ###############################################################################
55
+ # Group: Path String Functions
56
+
57
+
58
+ #
59
+ # Function: CanonizePath
60
+ #
61
+ # Takes a path and returns a logically simplified version of it.
62
+ #
63
+ # Why oh why?:
64
+ #
65
+ # Because File::Spec->canonpath doesn't strip quotes on Windows. So if you pass in "a b\c" or "a b"\c, they still end up as
66
+ # different strings even though they're logically the same.
67
+ #
68
+ # It also doesn't remove things like "..", so "a/b/../c" doesn't simplify to "a/c" like it should.
69
+ #
70
+ sub CanonizePath #(path)
71
+ {
72
+ my ($self, $path) = @_;
73
+
74
+ if ($::OSNAME eq 'MSWin32')
75
+ {
76
+ # We don't have to use a smarter algorithm for dropping quotes because they're invalid characters for actual file and
77
+ # directory names.
78
+ $path =~ s/\"//g;
79
+ };
80
+
81
+ $path = File::Spec->canonpath($path);
82
+
83
+ # Condense a/b/../c into a/c.
84
+
85
+ my $upDir = File::Spec->updir();
86
+ if (index($path, $upDir) != -1)
87
+ {
88
+ my ($volume, $directoryString, $file) = $self->SplitPath($path);
89
+ my @directories = $self->SplitDirectories($directoryString);
90
+
91
+ my $i = 1;
92
+ while ($i < scalar @directories)
93
+ {
94
+ if ($i > 0 && $directories[$i] eq $upDir && $directories[$i - 1] ne $upDir)
95
+ {
96
+ splice(@directories, $i - 1, 2);
97
+ $i--;
98
+ }
99
+ else
100
+ { $i++; };
101
+ };
102
+
103
+ $directoryString = $self->JoinDirectories(@directories);
104
+ $path = $self->JoinPath($volume, $directoryString, $file);
105
+ };
106
+
107
+ return $path;
108
+ };
109
+
110
+
111
+ #
112
+ # Function: PathIsAbsolute
113
+ #
114
+ # Returns whether the passed path is absolute.
115
+ #
116
+ sub PathIsAbsolute #(path)
117
+ {
118
+ my ($self, $path) = @_;
119
+ return File::Spec->file_name_is_absolute($path);
120
+ };
121
+
122
+
123
+ #
124
+ # Function: JoinPath
125
+ #
126
+ # Creates a path from its elements.
127
+ #
128
+ # Parameters:
129
+ #
130
+ # volume - The volume, such as the drive letter on Windows. Undef if none.
131
+ # dirString - The directory string. Create with <JoinDirectories()> if necessary.
132
+ # file - The file name, or undef if none.
133
+ #
134
+ # Returns:
135
+ #
136
+ # The joined path.
137
+ #
138
+ sub JoinPath #(volume, dirString, $file)
139
+ {
140
+ my ($self, $volume, $dirString, $file) = @_;
141
+ return File::Spec->catpath($volume, $dirString, $file);
142
+ };
143
+
144
+
145
+ #
146
+ # Function: JoinPaths
147
+ #
148
+ # Joins two paths.
149
+ #
150
+ # Parameters:
151
+ #
152
+ # basePath - May be a relative path, an absolute path, or undef.
153
+ # extraPath - May be a relative path, a file, a relative path and file together, or undef.
154
+ # noFileInExtra - Set this to true if extraPath is a relative path only, and doesn't have a file.
155
+ #
156
+ # Returns:
157
+ #
158
+ # The joined path.
159
+ #
160
+ # Why oh why?:
161
+ #
162
+ # Because nothing in File::Spec will simply slap two paths together. They have to be split up for catpath/file, and rel2abs
163
+ # requires the base to be absolute.
164
+ #
165
+ sub JoinPaths #(basePath, extraPath, noFileInExtra)
166
+ {
167
+ my ($self, $basePath, $extraPath, $noFileInExtra) = @_;
168
+
169
+ # If both are undef, it will return undef, which is what we want.
170
+ if (!defined $basePath)
171
+ { return $extraPath; }
172
+ elsif (!defined $extraPath)
173
+ { return $basePath; };
174
+
175
+ my ($baseVolume, $baseDirString, $baseFile) = File::Spec->splitpath($basePath, 1);
176
+ my ($extraVolume, $extraDirString, $extraFile) = File::Spec->splitpath($extraPath, $noFileInExtra);
177
+
178
+ my @baseDirectories = $self->SplitDirectories($baseDirString);
179
+ my @extraDirectories = $self->SplitDirectories($extraDirString);
180
+
181
+ my $fullDirString = $self->JoinDirectories(@baseDirectories, @extraDirectories);
182
+
183
+ my $fullPath = File::Spec->catpath($baseVolume, $fullDirString, $extraFile);
184
+
185
+ return $self->CanonizePath($fullPath);
186
+ };
187
+
188
+
189
+ #
190
+ # Function: SplitPath
191
+ #
192
+ # Takes a path and returns its elements.
193
+ #
194
+ # Parameters:
195
+ #
196
+ # path - The path to split.
197
+ # noFile - Set to true if the path doesn't have a file at the end.
198
+ #
199
+ # Returns:
200
+ #
201
+ # The array ( volume, directoryString, file ). If any don't apply, they will be undef. Use <SplitDirectories()> to split the
202
+ # directory string if desired.
203
+ #
204
+ # Why oh Why?:
205
+ #
206
+ # Because File::Spec->splitpath may leave a trailing slash/backslash/whatever on the directory string, which makes
207
+ # it a bit hard to match it with results from File::Spec->catdir.
208
+ #
209
+ sub SplitPath #(path, noFile)
210
+ {
211
+ my ($self, $path, $noFile) = @_;
212
+
213
+ my @segments = File::Spec->splitpath($path, $noFile);
214
+
215
+ if (!length $segments[0])
216
+ { $segments[0] = undef; };
217
+ if (!length $segments[2])
218
+ { $segments[2] = undef; };
219
+
220
+ $segments[1] = File::Spec->catdir( File::Spec->splitdir($segments[1]) );
221
+
222
+ return @segments;
223
+ };
224
+
225
+
226
+ #
227
+ # Function: JoinDirectories
228
+ #
229
+ # Creates a directory string from an array of directory names.
230
+ #
231
+ # Parameters:
232
+ #
233
+ # directory - A directory name. There may be as many of these as desired.
234
+ #
235
+ sub JoinDirectories #(directory, directory, ...)
236
+ {
237
+ my ($self, @directories) = @_;
238
+ return File::Spec->catdir(@directories);
239
+ };
240
+
241
+
242
+ #
243
+ # Function: SplitDirectories
244
+ #
245
+ # Takes a string of directories and returns an array of its elements.
246
+ #
247
+ # Why oh why?:
248
+ #
249
+ # Because File::Spec->splitdir might leave an empty element at the end of the array, which screws up both joining in
250
+ # <ConvertToURL> and navigation in <MakeRelativePath>.
251
+ #
252
+ sub SplitDirectories #(directoryString)
253
+ {
254
+ my ($self, $directoryString) = @_;
255
+
256
+ my @directories = File::Spec->splitdir($directoryString);
257
+
258
+ if (!length $directories[-1])
259
+ { pop @directories; };
260
+
261
+ return @directories;
262
+ };
263
+
264
+
265
+ #
266
+ # Function: MakeRelativePath
267
+ #
268
+ # Takes two paths and returns a relative path between them.
269
+ #
270
+ # Parameters:
271
+ #
272
+ # basePath - The starting path. May be relative or absolute, so long as the target path is as well.
273
+ # targetPath - The target path. May be relative or absolute, so long as the base path is as well.
274
+ #
275
+ # If both paths are relative, they are assumed to be relative to the same base.
276
+ #
277
+ # Returns:
278
+ #
279
+ # The target path relative to base.
280
+ #
281
+ # Why oh why?:
282
+ #
283
+ # First, there's nothing that gives a relative path between two relative paths.
284
+ #
285
+ # Second, if target and base are absolute but on different volumes, File::Spec->abs2rel creates a totally non-functional
286
+ # relative path. It should return the target as is, since there is no relative path.
287
+ #
288
+ # Third, File::Spec->abs2rel between absolute paths on the same volume, at least on Windows, leaves the drive letter
289
+ # on. So abs2rel('a:\b\c\d', 'a:\b') returns 'a:c\d' instead of the expected 'c\d'. That makes no sense whatsoever. It's
290
+ # not like it was designed to handle only directory names, either; the documentation says 'path' and the code seems to
291
+ # explicitly handle it. There's just an 'unless' in there that tacks on the volume, defeating the purpose of a *relative* path
292
+ # and making the function worthless.
293
+ #
294
+ sub MakeRelativePath #(basePath, targetPath)
295
+ {
296
+ my ($self, $basePath, $targetPath) = @_;
297
+
298
+ my ($baseVolume, $baseDirString, $baseFile) = $self->SplitPath($basePath, 1);
299
+ my ($targetVolume, $targetDirString, $targetFile) = $self->SplitPath($targetPath);
300
+
301
+ # If the volumes are different, there is no possible relative path.
302
+ if ($targetVolume ne $baseVolume)
303
+ { return $targetPath; };
304
+
305
+ my @baseDirectories = $self->SplitDirectories($baseDirString);
306
+ my @targetDirectories = $self->SplitDirectories($targetDirString);
307
+
308
+ # Skip the parts of the path that are the same.
309
+ while (scalar @baseDirectories && @targetDirectories && $baseDirectories[0] eq $targetDirectories[0])
310
+ {
311
+ shift @baseDirectories;
312
+ shift @targetDirectories;
313
+ };
314
+
315
+ # Back out of the base path until it reaches where they were similar.
316
+ for (my $i = 0; $i < scalar @baseDirectories; $i++)
317
+ {
318
+ unshift @targetDirectories, File::Spec->updir();
319
+ };
320
+
321
+ $targetDirString = $self->JoinDirectories(@targetDirectories);
322
+
323
+ return File::Spec->catpath(undef, $targetDirString, $targetFile);
324
+ };
325
+
326
+
327
+ #
328
+ # Function: IsSubPathOf
329
+ #
330
+ # Returns whether the path is a descendant of another path.
331
+ #
332
+ # Parameters:
333
+ #
334
+ # base - The base path to test against.
335
+ # path - The possible subpath to test.
336
+ #
337
+ # Returns:
338
+ #
339
+ # Whether path is a descendant of base.
340
+ #
341
+ sub IsSubPathOf #(base, path)
342
+ {
343
+ my ($self, $base, $path) = @_;
344
+
345
+ # This is a quick test that should find a false quickly.
346
+ if ($base eq substr($path, 0, length($base)))
347
+ {
348
+ # This doesn't guarantee true, because it could be "C:\A B" and "C:\A B C\File". So we test for it by seeing if the last
349
+ # directory in base is the same as the equivalent directory in path.
350
+
351
+ my ($baseVolume, $baseDirString, $baseFile) = NaturalDocs::File->SplitPath($base, 1);
352
+ my @baseDirectories = NaturalDocs::File->SplitDirectories($baseDirString);
353
+
354
+ my ($pathVolume, $pathDirString, $pathFile) = NaturalDocs::File->SplitPath($path);
355
+ my @pathDirectories = NaturalDocs::File->SplitDirectories($pathDirString);
356
+
357
+ return ( $baseDirectories[-1] eq $pathDirectories[ scalar @baseDirectories - 1 ] );
358
+ }
359
+ else
360
+ { return undef; };
361
+ };
362
+
363
+
364
+ #
365
+ # Function: ConvertToURL
366
+ #
367
+ # Takes a relative path and converts it from the native format to a relative URL. Note that it _doesn't_ convert special characters
368
+ # to amp chars.
369
+ #
370
+ sub ConvertToURL #(path)
371
+ {
372
+ my ($self, $path) = @_;
373
+
374
+ my ($pathVolume, $pathDirString, $pathFile) = $self->SplitPath($path);
375
+ my @pathDirectories = $self->SplitDirectories($pathDirString);
376
+
377
+ my $i = 0;
378
+ while ($i < scalar @pathDirectories && $pathDirectories[$i] eq File::Spec->updir())
379
+ {
380
+ $pathDirectories[$i] = '..';
381
+ $i++;
382
+ };
383
+
384
+ return join('/', @pathDirectories, $pathFile);
385
+ };
386
+
387
+
388
+ #
389
+ # Function: NoUpwards
390
+ #
391
+ # Takes an array of directory entries and returns one without all the entries that refer to the parent directory, such as '.' and '..'.
392
+ #
393
+ sub NoUpwards #(array)
394
+ {
395
+ my ($self, @array) = @_;
396
+ return File::Spec->no_upwards(@array);
397
+ };
398
+
399
+
400
+ #
401
+ # Function: NoFileName
402
+ #
403
+ # Takes a path and returns a version without the file name. Useful for sending paths to <CreatePath()>.
404
+ #
405
+ sub NoFileName #(path)
406
+ {
407
+ my ($self, $path) = @_;
408
+
409
+ my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
410
+
411
+ return File::Spec->catpath($pathVolume, $pathDirString, undef);
412
+ };
413
+
414
+
415
+ #
416
+ # Function: NoExtension
417
+ #
418
+ # Returns the path without an extension.
419
+ #
420
+ sub NoExtension #(path)
421
+ {
422
+ my ($self, $path) = @_;
423
+
424
+ my $extension = $self->ExtensionOf($path);
425
+
426
+ if ($extension)
427
+ { $path = substr($path, 0, length($path) - length($extension) - 1); };
428
+
429
+ return $path;
430
+ };
431
+
432
+
433
+ #
434
+ # Function: ExtensionOf
435
+ #
436
+ # Returns the extension of the passed path, or undef if none.
437
+ #
438
+ sub ExtensionOf #(path)
439
+ {
440
+ my ($self, $path) = @_;
441
+
442
+ my ($pathVolume, $pathDirString, $pathFile) = File::Spec->splitpath($path);
443
+
444
+ # We need the leading dot in the regex so files that start with a dot but don't have an extension count as extensionless files.
445
+ if ($pathFile =~ /.\.([^\.]+)$/)
446
+ { return $1; }
447
+ else
448
+ { return undef; };
449
+ };
450
+
451
+
452
+ #
453
+ # Function: IsCaseSensitive
454
+ #
455
+ # Returns whether the current platform has case-sensitive paths.
456
+ #
457
+ sub IsCaseSensitive
458
+ {
459
+ return !(File::Spec->case_tolerant());
460
+ };
461
+
462
+
463
+
464
+ ###############################################################################
465
+ # Group: Disk Functions
466
+
467
+
468
+ #
469
+ # Function: CreatePath
470
+ #
471
+ # Creates a directory tree corresponding to the passed path, regardless of how many directories do or do not already exist.
472
+ # Do _not_ include a file name in the path. Use <NoFileName()> first if you need to.
473
+ #
474
+ sub CreatePath #(path)
475
+ {
476
+ my ($self, $path) = @_;
477
+ File::Path::mkpath($path);
478
+ };
479
+
480
+
481
+ #
482
+ # Function: RemoveEmptyTree
483
+ #
484
+ # Removes an empty directory tree. The passed directory will be removed if it's empty, and it will keep removing its parents
485
+ # until it reaches one that's not empty or a set limit.
486
+ #
487
+ # Parameters:
488
+ #
489
+ # path - The path to start from. It will try to remove this directory and work it's way down.
490
+ # limit - The path to stop at if it doesn't find any non-empty directories first. This path will *not* be removed.
491
+ #
492
+ sub RemoveEmptyTree #(path, limit)
493
+ {
494
+ my ($self, $path, $limit) = @_;
495
+
496
+ my ($volume, $directoryString) = $self->SplitPath($path, 1);
497
+ my @directories = $self->SplitDirectories($directoryString);
498
+
499
+ my $directory = $path;
500
+
501
+ while (-d $directory && $directory ne $limit)
502
+ {
503
+ opendir FH_ND_FILE, $directory;
504
+ my @entries = readdir FH_ND_FILE;
505
+ closedir FH_ND_FILE;
506
+
507
+ @entries = $self->NoUpwards(@entries);
508
+
509
+ if (scalar @entries || !rmdir($directory))
510
+ { last; };
511
+
512
+ pop @directories;
513
+ $directoryString = $self->JoinDirectories(@directories);
514
+ $directory = $self->JoinPath($volume, $directoryString);
515
+ };
516
+ };
517
+
518
+
519
+ #
520
+ # Function: Copy
521
+ #
522
+ # Copies a file from one path to another. If the destination file exists, it is overwritten.
523
+ #
524
+ # Parameters:
525
+ #
526
+ # source - The file to copy.
527
+ # destination - The destination to copy to.
528
+ #
529
+ # Returns:
530
+ #
531
+ # Whether it succeeded
532
+ #
533
+ sub Copy #(source, destination) => bool
534
+ {
535
+ my ($self, $source, $destination) = @_;
536
+ return File::Copy::copy($source, $destination);
537
+ };
538
+
539
+
540
+ 1;