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