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