document the new test image functions
[imager.git] / apidocs.perl
CommitLineData
92bda632
TC
1#!perl -w
2use strict;
fe415ad2 3use ExtUtils::Manifest 'maniread';
92bda632
TC
4
5my $outname = shift || '-';
6
92bda632
TC
7my @funcs = make_func_list();
8my %funcs = map { $_ => 1 } @funcs;
9
10# look for files to parse
11
fe415ad2 12my $mani = maniread;
bd8052a6 13my @files = grep /\.(c|im|h)$/, keys %$mani;
92bda632
TC
14
15# scan each file for =item <func>\b
16my $func;
17my $start;
18my %alldocs;
19my @funcdocs;
20my %from;
21my $category;
22my %funccats;
23my %cats;
24my $synopsis = '';
25my %funcsyns;
6cfee9d1
TC
26my $order;
27my %order;
92bda632
TC
28for 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 ];
5ca7e2ab 40 $from{$func} = "File $file";
92bda632
TC
41 if ($category) {
42 $funccats{$func} = $category;
43 push @{$cats{$category}}, $func;
44 }
45 if ($synopsis) {
46 $funcsyns{$func} = $synopsis;
47 }
6cfee9d1
TC
48 defined $order or $order = 50;
49 $order{$func} = $order;
92bda632
TC
50 }
51 undef $func;
52 undef $category;
6cfee9d1 53 undef $order;
92bda632
TC
54 $synopsis = '';
55 }
56 elsif ($func) {
57 if (/^=category (.*)/) {
58 $category = $1;
59 }
60 elsif (/^=synopsis (.*)/) {
8d14daab
TC
61 unless (length $synopsis) {
62 push @funcdocs, "\n";
63 }
92bda632 64 $synopsis .= "$1\n";
8d14daab 65 push @funcdocs, " $1\n";
92bda632 66 }
6cfee9d1
TC
67 elsif (/^=order (.*)$/) {
68 $order = $1;
69 $order =~ /^\d+$/
70 or die "=order must specify a number for $func in $file\n";
71 }
92bda632
TC
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
83open OUT, "> $outname"
84 or die "Cannot open $outname: $!";
85
091760c5
TC
86# I keep this file in git and as part of the dist, make sure newlines
87# don't mess me up
88binmode OUT;
89
92bda632
TC
90print OUT <<'EOS';
91Do not edit this file, it is generated automatically by apidocs.perl
92from Imager's source files.
93
5ca7e2ab
TC
94Each function description has a comment listing the source file where
95you can find the documentation.
92bda632
TC
96
97=head1 NAME
98
6cfee9d1 99Imager::APIRef - Imager's C API - reference.
92bda632
TC
100
101=head1 SYNOPSIS
102
103 i_color color;
6cfee9d1 104 color.rgba.r = 255; color.rgba.g = 0; color.rgba.b = 255;
92bda632
TC
105
106EOS
107
108for my $cat (sort { lc $a cmp lc $b } keys %cats) {
109 print OUT "\n # $cat\n";
6cfee9d1 110 for my $func (grep $funcsyns{$_}, sort { $order{$a} <=> $order{$b} } @{$cats{$cat}}) {
92bda632
TC
111 my $syn = $funcsyns{$func};
112 $syn =~ s/^/ /gm;
113 print OUT $syn;
114 }
115}
116
117print OUT <<'EOS';
118
92bda632
TC
119=head1 DESCRIPTION
120
121EOS
122
123my %undoc = %funcs;
124
125for my $cat (sort { lc $a cmp lc $b } keys %cats) {
126 print OUT "=head2 $cat\n\n=over\n\n";
6cfee9d1
TC
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) {
92bda632
TC
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
50c75381 139# see if we have an uncategorised section
92bda632
TC
140if (grep $alldocs{$_}, keys %undoc) {
141 print OUT "=head2 Uncategorized functions\n\n=over\n\n";
6cfee9d1
TC
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};
92bda632
TC
148 }
149 print OUT "\n\n=back\n\n";
150}
151
152if (keys %undoc) {
153 print OUT <<'EOS';
154
155=head1 UNDOCUMENTED
156
157The following API functions are undocumented so far, hopefully this
158will change:
159
160=over
161
162EOS
163
164 print OUT "=item *\n\nB<$_>\n\n" for sort keys %undoc;
165
166 print OUT "\n\n=back\n\n";
167}
168
169print OUT <<'EOS';
170
171=head1 AUTHOR
172
5b480b14 173Tony Cook <tonyc@cpan.org>
92bda632
TC
174
175=head1 SEE ALSO
176
177Imager, Imager::ExtUtils, Imager::Inline
178
179=cut
180EOS
181
182close OUT;
183
184
185sub make_func_list {
8d14daab 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);
92bda632
TC
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}
6cfee9d1
TC
210
211=head1 NAME
212
213apidocs.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
221Parses Imager's C sources, including .c, .h and .im files searching
222for function documentation.
223
224Besides the normal POD markup, the following can be included:
225
226=over
227
228=item =category I<category-name>
229
230The category the function should be in.
231
232=item =synopsis I<sample-code>
233
234Sample code using the function to include in the Imager::APIRef SYNOPSIS
235
236=item =order I<integer>
237
238Allows a function to be listed out of order. If this isn't specified
239it defaults to 50, so a value of 10 will cause the function to be
240listed at the beginning of its category, or 90 to list at the end.
241
242Functions with equal order are otherwise ordered by name.
243
244=back
245
246=head1 AUTHOR
247
248Tony Cook <tonyc@cpan.org>
249
250=cut
251