Move freetype 2 support into its own module
[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 (.*)/) {
61 $synopsis .= "$1\n";
62 }
6cfee9d1
TC
63 elsif (/^=order (.*)$/) {
64 $order = $1;
65 $order =~ /^\d+$/
66 or die "=order must specify a number for $func in $file\n";
67 }
92bda632
TC
68 else {
69 push @funcdocs, $_;
70 }
71 }
72 }
73 $func and
74 die "Documentation for $func not followed by =cut or =head in $file\n";
75
76 close SRC;
77}
78
79open OUT, "> $outname"
80 or die "Cannot open $outname: $!";
81
82print OUT <<'EOS';
83Do not edit this file, it is generated automatically by apidocs.perl
84from Imager's source files.
85
5ca7e2ab
TC
86Each function description has a comment listing the source file where
87you can find the documentation.
92bda632
TC
88
89=head1 NAME
90
6cfee9d1 91Imager::APIRef - Imager's C API - reference.
92bda632
TC
92
93=head1 SYNOPSIS
94
95 i_color color;
6cfee9d1 96 color.rgba.r = 255; color.rgba.g = 0; color.rgba.b = 255;
92bda632
TC
97
98EOS
99
100for my $cat (sort { lc $a cmp lc $b } keys %cats) {
101 print OUT "\n # $cat\n";
6cfee9d1 102 for my $func (grep $funcsyns{$_}, sort { $order{$a} <=> $order{$b} } @{$cats{$cat}}) {
92bda632
TC
103 my $syn = $funcsyns{$func};
104 $syn =~ s/^/ /gm;
105 print OUT $syn;
106 }
107}
108
109print OUT <<'EOS';
110
92bda632
TC
111=head1 DESCRIPTION
112
113EOS
114
115my %undoc = %funcs;
116
117for my $cat (sort { lc $a cmp lc $b } keys %cats) {
118 print OUT "=head2 $cat\n\n=over\n\n";
6cfee9d1
TC
119 my @ordered_funcs = sort {
120 $order{$a} <=> $order{$b}
121 || lc $a cmp lc $b
122 } @{$cats{$cat}};
123 for my $func (@ordered_funcs) {
92bda632
TC
124 print OUT @{$alldocs{$func}}, "\n";
125 print OUT "=for comment\nFrom: $from{$func}\n\n";
126 delete $undoc{$func};
127 }
128 print OUT "\n=back\n\n";
129}
130
50c75381 131# see if we have an uncategorised section
92bda632
TC
132if (grep $alldocs{$_}, keys %undoc) {
133 print OUT "=head2 Uncategorized functions\n\n=over\n\n";
6cfee9d1
TC
134 #print join(",", grep !exists $order{$_}, @funcs), "\n";
135 for my $func (sort { $order{$a} <=> $order{$b} || $a cmp $b }
136 grep $undoc{$_} && $alldocs{$_}, @funcs) {
137 print OUT @{$alldocs{$func}}, "\n";
138 print OUT "=for comment\nFrom: $from{$func}\n\n";
139 delete $undoc{$func};
92bda632
TC
140 }
141 print OUT "\n\n=back\n\n";
142}
143
144if (keys %undoc) {
145 print OUT <<'EOS';
146
147=head1 UNDOCUMENTED
148
149The following API functions are undocumented so far, hopefully this
150will change:
151
152=over
153
154EOS
155
156 print OUT "=item *\n\nB<$_>\n\n" for sort keys %undoc;
157
158 print OUT "\n\n=back\n\n";
159}
160
161print OUT <<'EOS';
162
163=head1 AUTHOR
164
165Tony Cook <tony@imager.perl.org>
166
167=head1 SEE ALSO
168
169Imager, Imager::ExtUtils, Imager::Inline
170
171=cut
172EOS
173
174close OUT;
175
176
177sub make_func_list {
6cfee9d1 178 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);
92bda632
TC
179 open FUNCS, "< imexttypes.h"
180 or die "Cannot open imexttypes.h: $!\n";
181 my $in_struct;
182 while (<FUNCS>) {
183 /^typedef struct/ && ++$in_struct;
184 if ($in_struct && /\(\*f_(i_\w+)/) {
185 push @funcs, $1;
186 }
187 if (/^\} im_ext_funcs;$/) {
188 $in_struct
189 or die "Found end of functions structure but not the start";
190
191 close FUNCS;
192 return @funcs;
193 }
194 }
195 if ($in_struct) {
196 die "Found start of the functions structure but not the end\n";
197 }
198 else {
199 die "Found neither the start nor end of the functions structure\n";
200 }
201}
6cfee9d1
TC
202
203=head1 NAME
204
205apidocs.perl - parse Imager's source for POD documenting the C API
206
207=head1 SYNOPSIS
208
209 perl apidocs.perl lib/Imager/APIRef.pod
210
211=head1 DESCRIPTION
212
213Parses Imager's C sources, including .c, .h and .im files searching
214for function documentation.
215
216Besides the normal POD markup, the following can be included:
217
218=over
219
220=item =category I<category-name>
221
222The category the function should be in.
223
224=item =synopsis I<sample-code>
225
226Sample code using the function to include in the Imager::APIRef SYNOPSIS
227
228=item =order I<integer>
229
230Allows a function to be listed out of order. If this isn't specified
231it defaults to 50, so a value of 10 will cause the function to be
232listed at the beginning of its category, or 90 to list at the end.
233
234Functions with equal order are otherwise ordered by name.
235
236=back
237
238=head1 AUTHOR
239
240Tony Cook <tonyc@cpan.org>
241
242=cut
243