]> git.imager.perl.org - imager.git/blob - apidocs.perl
fix the link in the getheight() entry in the method index
[imager.git] / apidocs.perl
1 #!perl -w
2 use strict;
3 use ExtUtils::Manifest 'maniread';
4
5 my $outname = shift || '-';
6
7 my @funcs = make_func_list();
8 my %funcs = map { $_ => 1 } @funcs;
9
10 # look for files to parse
11
12 my $mani = maniread;
13 my @files = grep /\.(c|im|h)$/, keys %$mani;
14
15 # scan each file for =item <func>\b
16 my $func;
17 my $start;
18 my %alldocs;
19 my @funcdocs;
20 my %from;
21 my $category;
22 my %funccats;
23 my %cats;
24 my $synopsis = '';
25 my %funcsyns;
26 my $order;
27 my %order;
28 for my $file (@files) {
29   open SRC, "< $file"
30     or die "Cannot open $file for documentation: $!\n";
31   while (<SRC>) {
32     if (/^=item (\w+)\b/ && $funcs{$1}) {
33       $func = $1;
34       $start = $.;
35       @funcdocs = $_;
36     }
37     elsif ($func && /^=(cut|head)/) {
38       if ($funcs{$func}) { # only save the API functions
39         $alldocs{$func} = [ @funcdocs ];
40         $from{$func} = "File $file";
41         if ($category) {
42           $funccats{$func} = $category;
43           push @{$cats{$category}}, $func;
44         }
45         if ($synopsis) {
46           $funcsyns{$func} = $synopsis;
47         }
48         defined $order or $order = 50;
49         $order{$func} = $order;
50       }
51       undef $func;
52       undef $category;
53       undef $order;
54       $synopsis = '';
55     }
56     elsif ($func) {
57       if (/^=category (.*)/) {
58         $category = $1;
59       }
60       elsif (/^=synopsis (.*)/) {
61         unless (length $synopsis) {
62           push @funcdocs, "\n";
63         }
64         $synopsis .= "$1\n";
65         push @funcdocs, "  $1\n";
66       }
67       elsif (/^=order (.*)$/) {
68         $order = $1;
69         $order =~ /^\d+$/
70           or die "=order must specify a number for $func in $file\n";
71       }
72       else {
73         push @funcdocs, $_;
74       }
75     }
76   }
77   $func and
78     die "Documentation for $func not followed by =cut or =head in $file\n";
79   
80   close SRC;
81 }
82
83 open OUT, "> $outname"
84   or die "Cannot open $outname: $!";
85
86 # I keep this file in git and as part of the dist, make sure newlines
87 # don't mess me up
88 binmode OUT;
89
90 print OUT <<'EOS';
91 Do not edit this file, it is generated automatically by apidocs.perl
92 from Imager's source files.
93
94 Each function description has a comment listing the source file where
95 you can find the documentation.
96
97 =head1 NAME
98
99 Imager::APIRef - Imager's C API - reference.
100
101 =head1 SYNOPSIS
102
103   i_color color;
104   color.rgba.r = 255; color.rgba.g = 0; color.rgba.b = 255;
105
106 EOS
107
108 for my $cat (sort { lc $a cmp lc $b } keys %cats) {
109   print OUT "\n  # $cat\n";
110   for my $func (grep $funcsyns{$_}, sort { $order{$a} <=> $order{$b} } @{$cats{$cat}}) {
111     my $syn = $funcsyns{$func};
112     $syn =~ s/^/  /gm;
113     print OUT $syn;
114   }
115 }
116
117 print OUT <<'EOS';
118
119 =head1 DESCRIPTION
120
121 EOS
122
123 my %undoc = %funcs;
124
125 for my $cat (sort { lc $a cmp lc $b } keys %cats) {
126   print OUT "=head2 $cat\n\n=over\n\n";
127   my @ordered_funcs = sort {
128     $order{$a} <=> $order{$b}
129       || lc $a cmp lc $b
130     } @{$cats{$cat}};
131   for my $func (@ordered_funcs) {
132     print OUT @{$alldocs{$func}}, "\n";
133     print OUT "=for comment\nFrom: $from{$func}\n\n";
134     delete $undoc{$func};
135   }
136   print OUT "\n=back\n\n";
137 }
138
139 # see if we have an uncategorised section
140 if (grep $alldocs{$_}, keys %undoc) {
141   print OUT "=head2 Uncategorized functions\n\n=over\n\n";
142   #print join(",", grep !exists $order{$_}, @funcs), "\n";
143   for my $func (sort { $order{$a} <=> $order{$b} || $a cmp $b }
144                 grep $undoc{$_} && $alldocs{$_}, @funcs) {
145     print OUT @{$alldocs{$func}}, "\n";
146     print OUT "=for comment\nFrom: $from{$func}\n\n";
147     delete $undoc{$func};
148   }
149   print OUT "\n\n=back\n\n";
150 }
151
152 if (keys %undoc) {
153   print OUT <<'EOS';
154
155 =head1 UNDOCUMENTED
156
157 The following API functions are undocumented so far, hopefully this
158 will change:
159
160 =over
161
162 EOS
163
164   print OUT "=item *\n\nB<$_>\n\n" for sort keys %undoc;
165
166   print OUT "\n\n=back\n\n";
167 }
168
169 print OUT <<'EOS';
170
171 =head1 AUTHOR
172
173 Tony Cook <tonyc@cpan.org>
174
175 =head1 SEE ALSO
176
177 Imager, Imager::ExtUtils, Imager::Inline
178
179 =cut
180 EOS
181
182 close OUT;
183
184
185 sub make_func_list {
186   my @funcs = qw(i_img i_color i_fcolor i_fill_t mm_log i_img_color_channels i_img_has_alpha i_img_dim i_DF i_DFc i_DFp i_DFcp);
187   open FUNCS, "< imexttypes.h"
188     or die "Cannot open imexttypes.h: $!\n";
189   my $in_struct;
190   while (<FUNCS>) {
191     /^typedef struct/ && ++$in_struct;
192     if ($in_struct && /\(\*f_(i_\w+)/) {
193       push @funcs, $1;
194     }
195     if (/^\} im_ext_funcs;$/) {
196       $in_struct
197         or die "Found end of functions structure but not the start";
198
199       close FUNCS;
200       return @funcs;
201     }
202   }
203   if ($in_struct) {
204     die "Found start of the functions structure but not the end\n";
205   }
206   else {
207     die "Found neither the start nor end of the functions structure\n";
208   }
209 }
210
211 =head1 NAME
212
213 apidocs.perl - parse Imager's source for POD documenting the C API
214
215 =head1 SYNOPSIS
216
217   perl apidocs.perl lib/Imager/APIRef.pod
218
219 =head1 DESCRIPTION
220
221 Parses Imager's C sources, including .c, .h and .im files searching
222 for function documentation.
223
224 Besides the normal POD markup, the following can be included:
225
226 =over
227
228 =item =category I<category-name>
229
230 The category the function should be in.
231
232 =item =synopsis I<sample-code>
233
234 Sample code using the function to include in the Imager::APIRef SYNOPSIS
235
236 =item =order I<integer>
237
238 Allows a function to be listed out of order.  If this isn't specified
239 it defaults to 50, so a value of 10 will cause the function to be
240 listed at the beginning of its category, or 90 to list at the end.
241
242 Functions with equal order are otherwise ordered by name.
243
244 =back
245
246 =head1 AUTHOR
247
248 Tony Cook <tonyc@cpan.org>
249
250 =cut
251