[exdoc] Fix whitespace.
[mono.git] / docs / exdoc
1 #!/usr/bin/perl
2
3 if ($ARGV[0] eq "-h") {
4     $sourcedir = $ARGV[1];
5     $dir = $sourcedir;
6     $html = 1;
7     shift @ARGV;
8     shift @ARGV;
9 }
10 open (FILE, "$dir/api-style.css" || die "Did not find $dir/api-style.css");
11 while (<FILE>) {
12     $css = $css . $_;
13 }
14
15 if ($ARGV[0] eq "-t") {
16     $dir = $ARGV[1];
17     shift @ARGV;
18 }
19
20 if ($html) {
21     opendir (D, "$sourcedir/sources/") || die "Can not open $dir";
22     while ($n = readdir (D)) {
23         if ($n =~ /mono-api-.*\.html$/) {
24             open (IN, "$sourcedir/sources/$n") || die "Can not open $n";
25             $files[$filecount] = $n;
26             while (<IN>) {
27                 @files_content[$filecount] .= $_;
28                 if (/name="api:(.*?)"/) {
29                     $_ =~ s/.*name="api:(\w+?)".*/\1/;
30                     $apis[$filecount] .= "$_";
31                 }
32             }
33             $filecount++;
34             close IN;
35         }
36     }
37 }
38
39 while (<ARGV>) {
40     if (/\/\*\* *\n/) {
41         &process_doc;
42     } else {
43         #print "IGNORING: $_";
44     }
45 }
46
47 if ($html) {
48     for ($f = 0; $f < $filecount; $f++) {
49         $name = $files[$f];
50         open (OUT, "> $dir/html/$name") || die "Can not create $dir/html/$name";
51         print "Merging: $name\n";
52         print OUT <<EOF;
53 <?xml version="1.0" encoding="utf-8"?>
54 <html xmlns="http://www.w3.org/1999/xhtml">
55 <head>
56     <title>$name</title>
57     <style type="text/css">
58 $css
59    </style>
60 </head>
61 <body>
62 <div class="mapi-docs">
63 EOF
64         @a = split (/\n/, $files_content[$f]);
65         $strikeextra = "";
66         $api_shown = 0;
67         for ($ai = 0; $ai < $#a; $ai++) {
68             $line = $a[$ai];
69
70             ($api, $caption) = $line =~ /<h4><a name=\"api:(\w+)\">(\w+)<\/a><\/h4>/;
71             if ($api ne "") {
72                 if ($api_shown == 1) {
73                     print OUT "</div> <!-- class=mapi -->\n\n";
74                     if ($deprecated{$api}) {
75                         $strike = "mapi-strike";
76                         $strikeextra = "</div><br><div class='mapi-deprecated'><b>Deprecated:</b> " . $deprecated{$api};
77                     } else {
78                         $strike = "";
79                         $strikeextra = "";
80                     }
81                 }
82                 $api_shown = 1;
83                 $proto = $prototype{$api};
84                 if ($proto eq "") {
85                     $proto = "$api";
86                 }
87
88                 print OUT <<EOF;
89 <a name="api:$api"></a>
90 <div class="mapi">
91     <div class="mapi-entry $strike"><code>$api$strikeextra</code></div>
92     <div class="mapi-height-container">
93         <div class="mapi-ptr-container"></div>
94         <div class="mapi-description">
95             <div class="mapi-ptr"></div>
96
97             <div class="mapi-declaration mapi-section">Syntax</div>
98             <div class="mapi-prototype">$proto</div>
99             <p>
100 EOF
101                 $ppars = $arguments{$api};
102                 if ($ppars ne "" && (!($ppars =~ /^[ \t]+$/))) {
103                     print OUT "            <div class=\"mapi-section\">Parameters</div>\n";
104                     print OUT "            <table class=\"mapi-parameters\"><tbody>".${arguments{$api}}."</tbody></table>";
105                 }
106
107                 &opt_print ("Return value", $returns{$api}, 0);
108                 &opt_print ("Description", $bodies{$api}, 0);
109                 print OUT "        </div><!--mapi-description-->\n    </div><!--height container-->\n";
110             } else {
111                 if ($line =~ /@API_IDX@/) {
112                     $apis_toc = &create_toc ($apis[$f]);
113                     $line =~ s/\@API_IDX\@/$apis_toc/;
114                 }
115                 if ($line =~ /^<h4/) {
116                     print OUT "</div>\n";
117                     $api_shown = 0;
118                 }
119                 if ($line =~ /`/) {
120                 }
121                 print OUT "$line\n";
122             }
123         }
124         print OUT <<EOF;
125    </div>
126 </body>
127 </html>
128 EOF
129         close OUT;
130         system ("$ENV{runtimedir}/mono-wrapper convert.exe $dir/html/$name $dir/html/x-$name");
131
132
133         # clean up the mess that AgilityPack does, it CDATAs our CSS
134         open HACK, "$dir/html/x-$name" || die "Could not open $dir/html/x-$name";
135         open HACKOUT, ">$dir/deploy/$name" || die "Could not open output";
136
137         $line = 0;
138         $doprint = 0;
139         while (<HACK>) {
140             print HACKOUT $last if ($doprint);
141             $line++;
142             s/^\/\/<!\[CDATA\[//;
143             s/^\/\/\]\]>\/\///;
144
145             # Remove the junk <span> wrapper generated by AgilityPack
146             if ($line==1) {
147                 s/<span>//;
148             }
149             if (/<style type/) {
150                 # Replace the CSS in the XHTML output with the original CSS
151                 print HACKOUT $_;
152                 print HACKOUT $css;
153                 while (<HACK>) {
154                     last if (/<\/style>/);
155                 }
156             }
157             $last = $_;
158             $doprint = 1;
159         }
160         if (!($last =~ /span/)) {
161             print HACKOUT $last;
162         }
163
164         # system ("cp.exe $dir/html/$name $dir/deploy/$name");
165     }
166 }
167
168 sub process_doc {
169     $doc = "";
170     $func = <>;
171     chop $func;
172     $func =~ s/^ \* //;
173     $func =~ s/:$//;
174     print "Function: $func\n" if (!$html);
175     $args = "";
176     $inbody = 0;
177     $returns = "";
178     $body = "";
179     $functions[$fn++] = $func;
180     $deprecated = 0;
181     # Process arguments
182     while (<>) {
183         s/NULL/<code>NULL<\/code>/g;
184         s/TRUE/<code>TRUE<\/code>/g;
185         s/FALSE/<code>FALSE<\/code>/g;
186         if (/^ \*\*?\//) {
187             $body =~ s/@(\w+)/<i>\1<\/i>/g;
188             $returns =~ s/@(\w+)/<i>\1<\/i>/g;
189             $args =~ s/@(\w+)/<i>\1<\/i>/g;
190
191             $body =~ s/#(\w+)/<code>\1<\/code>/g;
192             $returns =~ s/#(\w+)/<code>\1<\/code>/g;
193             $args =~ s/#(\w+)/<code>\1<\/code>/g;
194
195             $returns =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
196             $args =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
197             $body =~ s/\`([:.\w\*]+)\`/<code>\1<\/code>/g;
198
199             $body =~ s/\n/ /;
200             $bodies{$func} = $body;
201             $arguments{$func} = $args;
202             $deprecated{$func} = $deprecated;
203             $returns{$func} = $returns;
204             $proto = "";
205             while (<>) {
206                 $proto .= $_;
207                 last if (/\{/);
208             }
209             $proto =~ s/{//;
210             # clean it up a little, remove newlines, empty space at end
211             $proto =~ s/ +$//;
212             # Turn "Type * xxx" into "Type* xxx"
213             $proto =~ s/^(\w+)\W+\*/\1\*/;
214             $prototype{$func} = $proto;
215             return;
216         }
217         chop;
218         s/^\ \*//;
219         $_ = "<p>" if (/^\s*$/);
220
221         if ($inbody == 0) {
222             if (/\s*(\w+):(.*)/) {
223                 if ($1 eq "deprecated") {
224                     $deprecated = $2;
225                 } else {
226                     # $args .= "<dt><i>$1:</i></dt><dd>$2</dd>";
227                     $args .= "<tr><td><i>$1</i><td>$2</td></td></tr>";
228                 }
229             } else {
230
231                 $body = "\t$_\n";
232
233                 $inbody = 1;
234             }
235         } elsif ($inbody == 1) {
236             if (/Returns?:/) {
237                 s/Returns?://;
238                 $returns = "\t$_\n";
239                 $inbody = 2;
240             } else {
241                 $body .= "\n\t$_";
242             }
243         } else {
244             $returns .= "\n\t$_";
245         }
246
247     }
248 }
249
250 sub create_toc {
251     my ($apis_listed) = @_;
252     my $type_size = 0;
253     my $name_size = 0;
254     my $ret, $xname, $args, $line;
255     $apis_toc = "";
256
257
258     # Try to align things, so compute type size, method size, and arguments
259     foreach $line (split /\n/, $apis_listed) {
260         $p = $prototype{$line};
261         ($ret, $xname, $args) = $p =~ /(.*)\n(\w+)[ \t](.*)/;
262         $tl = length ($ret);
263         $pl = length ($xname);
264
265         $type_size = $tl if ($tl > $type_size);
266         $name_size = $pl if ($pl > $name_size);
267     }
268
269     $type_size++;
270     $name_size++;
271
272     foreach $line (split /\n/, $apis_listed) {
273         chop;
274         $p = $prototype{$line};
275         ($ret, $xname, $args) = $p =~ /(.*)\n(\w+)[ \t](.*)/;
276         if ($xname eq "") {
277             $xname = $line;
278         }
279
280         $rspace = " " x ($type_size - length ($ret));
281         $nspace = " " x ($name_size - length ($xname));
282         $args = &format ($args, length ($ret . $rspace . $xname . $nspace), 60);
283         $apis_toc .= "$ret$rspace<a href=\"\#api:$line\">$xname</a>$nspace$args\n";
284     }
285     return $apis_toc;
286 }
287
288 #
289 # Formats the rest of the arguments in a way that will fit in N columns
290 #
291 sub format {
292     my ($args, $size, $limit) = @_;
293     my $sret = "";
294
295     # return $args if ((length (args) + size) < $limit);
296     
297     $remain = $limit - $size;
298     @sa = split /,/, $args;
299     $linelen = $size;
300     foreach $arg (@sa) {
301         if ($sret eq "") {
302             $sret = $arg . ", ";
303             $linelen += length ($sret);
304         } else {
305             if ($linelen + length ($arg) < $limit) {
306                 $sret .= "FITS" . $arg . ", ";
307             } else {
308                 $newline = " " x ($size) . $arg . ", ";
309                 $linelen = length ($newline);
310                 $sret .= "\n" . $newline;
311             }
312         }
313     }
314     $sret =~ s/, $/;/;
315     return $sret;
316 }
317
318 sub opt_print {
319     my ($caption, $opttext, $quote) = @_;
320
321     if ($opttext ne "" && (!($opttext =~ /^[ \t]+$/))) {
322         print OUT "             <div class=\"mapi-section\">$caption</div>\n";
323         print OUT "             <div>$opttext</div>\n";
324     }
325 }