]> granicus.if.org Git - imagemagick/blob - scripts/format_c_api_docs
(no commit message)
[imagemagick] / scripts / format_c_api_docs
1 #!/usr/bin/perl -w
2 #
3 # Format ImageMagick comments into POD-format or HTML format
4 # documentation
5 # Produces *.pod or *.html files corresponding to *.c files
6 #
7 # Written by Bob Friesenhahn, April 1997
8 #
9
10 $opt_format='html';
11 $opt_srcdir='';
12 $opt_outdir='';
13
14 use Getopt::Long;
15 if ( ! GetOptions(
16                   'format=s'    => \$opt_format,
17                   'srcdir=s'    => \$opt_srcdir,
18                   'outdir=s'    => \$opt_outdir,
19                  )
20    ) {
21   print("Usage: fmtdocs [-srcdir srcdir] [-outdir outdir] [-format format] \n");
22   exit(1);
23 }
24
25 #
26 # Source files to use
27 #
28 @srcs = ('animate.c',
29          'annotate.c',
30          'attribute.c',
31          'blob.c',
32          'cache.c',
33          'cache-view.c',
34          'color.c',
35          'colorspace.c',
36          'compare.c',
37          'composite.c',
38          'constitute.c',
39          'decorate.c',
40    'deprecate.c',
41          'draw.c',
42          'drawing-wand.c',
43          'display.c',
44          'effect.c',
45          'enhance.c',
46          'exception.c',
47          'fx.c',
48          'image.c',
49          'list.c',
50          'magick.c',
51          'magick-wand.c',
52          'memory.c',
53          'monitor.c',
54          'montage.c',
55    'paint.c',
56          'pixel-iterator.c',
57          'pixel-wand.c',
58          'profile.c',
59          'quantize.c',
60          'registry.c',
61    'resource.c',
62          'segment.c',
63          'shear.c',
64          'signature.c',
65          'stream.c',
66          'transform.c',
67          'resize.c',
68    'version.c');
69
70 $tmpname_pre_format = "/tmp/fmtdocs_pre.$$";
71 $tmpname_pod = "/tmp/fmtdocs_pod.$$";
72 $tmpname_html = "/tmp/fmtdocs_html.$$";
73
74 #@srcs = ('draw.c');
75
76 #
77 # What is for source files
78 #
79 %whatis =
80 (
81  'animate',     'Interactively Animate an Image Sequence',
82  'annotate',    'Annotate an Image',
83  'attribute',   'Set Text Attributes',
84  'blob',        'Read or Write Binary Large OBjects',
85  'color',       'Count the Colors in an Image',
86  'colorspace',  'Dealing with Image Colorspaces',
87  'compare',     'Compare an Image to a Reconstructed Image',
88  'constitute',  'Constitute an Image',
89  'composite',   'Composite an Image',
90  'decorate',    'Decorate an Image',
91  'deprecate',   'Deprecated Methods',
92  'display',     'Interactively Display and Edit an Image',
93  'draw',        'Draw on an Image',
94  'drawing_wand',        'Image Vector Drawing',
95  'effect',      'Add an Effect',
96  'fx',          'Add a Special Effect',
97  'enhance',     'Enhance an Image',
98  'exception',   'Dealing with Exceptions',
99  'image',       'Image Methods',
100  'list',        'Working with Image Lists',
101  'cache',       'Get or Set Image Pixels',
102  'cache_view',  'Working with Cache Views',
103  'magick',      'Read or List Image formats',
104  'magick_wand', 'Magick Wand',
105  'memory',      'Memory Allocation',
106  'monitor',     'Monitor the Progress of an Image Operation',
107  'montage',     'Create an Image Thumbnail',
108  'paint',       'Paint on an Image',
109  'pixel_iterator',      'Pixel Iterator',
110  'pixel_wand',  'Pixel Wand',
111  'profile',     'Dealing with Image Profiles',
112  'quantize',    'Reduce the Number of Unique Colors in an Image',
113  'registry',    'The Registry',
114  'resource',    'Minitor or Limit Resource Consumption',
115  'segment',     'Segment an Image with Thresholding Fuzzy c-Means',
116  'shear',       'Shear or Rotate an Image by an Arbitrary Angle',
117  'signature',   'Compute a Digital Signature for an Image',
118  'stream',      'The Pixel FIFO',
119  'transform',   'Transform an Image',
120  'resize',      'Resize an Image',
121  'version',     'Get Version and Copyright',
122 );
123
124 #
125 # Key words to replace with HTML links
126 #
127 my %keywords =
128   (
129    AffineMatrix         => 'types.html#AffineMatrix',
130    BlobInfo             => 'types.html#BlobInfo',
131    Cache                => 'types.html#Cache',
132    ChannelType          => 'types.html#ChannelType',
133    ChromaticityInfo     => 'types.html#ChromaticityInfo',
134    ClassType            => 'types.html#ClassType',
135    ClipPathUnits        => 'types.html#ClipPathUnits',
136    ColorPacket          => 'types.html#ColorPacket',
137    ColorspaceType       => 'types.html#ColorspaceType',
138    ComplianceType       => 'types.html#ComplianceType',
139    CompositeOperator    => 'types.html#CompositeOperator',
140    CompressionType      => 'types.html#CompressionType',
141    DecorationType       => 'types.html#DecorationType',
142    DrawContext          => 'types.html#DrawContext',
143    DrawInfo             => 'types.html#DrawInfo',
144    ErrorHandler         => 'types.html#ErrorHandler',
145    ExceptionInfo        => 'types.html#ExceptionInfo',
146    ExceptionType        => 'types.html#ExceptionType',
147    FillRule             => 'types.html#FillRule',
148    FilterTypes          => 'types.html#FilterTypes',
149    FrameInfo            => 'types.html#FrameInfo',
150    GravityType          => 'types.html#GravityType',
151    Image                => 'types.html#Image',
152    ImageInfo            => 'types.html#ImageInfo',
153    ImageType            => 'types.html#ImageType',
154    InterlaceType        => 'types.html#InterlaceType',
155    LayerType            => 'types.html#LayerType',
156    MagickInfo           => 'types.html#MagickInfo',
157    MonitorHandler       => 'types.html#MonitorHandler',
158    MontageInfo          => 'types.html#MontageInfo',
159    NoiseType            => 'types.html#NoiseType',
160    PaintMethod          => 'types.html#PaintMethod',
161    PixelPacket          => 'types.html#PixelPacket',
162    PointInfo            => 'types.html#PointInfo',
163    ProfileInfo          => 'types.html#ProfileInfo',
164    QuantizeInfo         => 'types.html#QuantizeInfo',
165    Quantum              => 'types.html#Quantum',
166    QuantumType          => 'types.html#QuantumType',
167    RectangleInfo        => 'types.html#RectangleInfo',
168    RegistryType         => 'types.html#RegistryType',
169    RenderingIntent      => 'types.html#RenderingIntent',
170    ResolutionType       => 'types.html#ResolutionType',
171    ResourceType         => 'types.html#ResourceType',
172    SegmentInfo          => 'types.html#SegmentInfo',
173    SignatureInfo        => 'types.html#SignatureInfo',
174    StorageType          => 'types.html#StorageType',
175    StreamHandler        => 'types.html#StreamHandler',
176    StretchType          => 'types.html#StretchType',
177    StyleType            => 'types.html#StyleType',
178    TypeMetric           => 'types.html#TypeMetric',
179    CacheView            => 'types.html#CacheView',
180    VirtualPixelMethod   => 'types.html#VirtualPixelMethod',
181    XResourceInfo        => 'types.html#XResourceInfo',
182 );
183
184
185 foreach $src (@srcs) {
186
187   my($out,$command);
188
189   # Compute POD name
190   ($base = $src) =~ s/\.[^\.]*$//g;
191
192   $out = "${base}.${opt_format}";
193   if ("${opt_outdir}" ne "") {
194     $out = "${opt_outdir}/${base}.${opt_format}";
195   }
196
197   if ("${opt_srcdir}" ne "") {
198     $src = "${opt_srcdir}/${src}";
199   }
200
201   $command='pod2html -netscape';
202   if ( $opt_format eq 'html' ) {
203     $command='pod2html -netscape';
204   } elsif ( $opt_format eq 'latex' ) {
205     $command='pod2latex';
206   } elsif ( $opt_format eq 'man' ) {
207     $command='pod2man';
208   } elsif ( $opt_format eq 'text' ) {
209     $command='pod2text';
210   } elsif ( $opt_format eq 'pod' ) {
211     $command='cat';
212   }
213
214   print( "Processing $src -> $out\n" );
215
216   pre_format($src, $tmpname_pre_format);                # Make easily parsed
217   format_to_pod($tmpname_pre_format, $tmpname_pod);     # Format to pod.
218
219   if ( $opt_format eq 'html' ) {
220     system("$command $tmpname_pod > \"$tmpname_html\"");
221     reformat_html($tmpname_html,$out);
222   } else {
223     system("$command $tmpname_pod > \"$out\"");
224   }
225   unlink($tmpname_pre_format);
226   unlink($tmpname_pod);
227   unlink($tmpname_html);
228 }
229
230 #unlink($tmpname_pre_format);
231 exit(0);
232
233 #
234 # Reformat pod2html-generated HTML into nicer form.
235 #
236 sub reformat_html {
237   my($infile, $outfile) = @_;
238
239   open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
240   open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
241
242  INPUT:
243   while(<IN>) {
244     s|<\!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">|<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
245   "http://www.w3.org/TR/html4/loose.dtd">|;
246     s|<HEAD>|<HEAD>
247 <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
248 <STYLE>
249 <!--
250 \@page { size: 8.5in 11in }
251 TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
252 P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
253 H2 { color: #000000 }
254 A:link { color: #0085c0 }
255 A:visited { color: #800080 }
256 -->
257 </STYLE>
258 |;
259     s|<link rev="made" href="mailto:root\@localhost" />|<link rel="stylesheet" type="text/css" href="../magick.css">|;
260     s|<body style="background-color: white">|<body marginheight="1" marginwidth="1" topmargin="1" leftmargin="1">
261 <a name="top"></a> 
262 <table border="0" cellpadding="0" cellspacing="0" summary="Masthead" width="100%">
263 <tbody>
264 <tr>
265 <td bgcolor="#003399" width="25%" height="118" background="../../images/background.gif"><a href="http://www.imagemagick.org/"><img src="../../images/script.gif" width="278" height="118" border="0" alt="" /></a></td>
266 <td bgcolor="#003399" width="60%" height="118" background="../../images/background.gif"><a href="http://www.networkeleven.com/direct.php?magick_all"><img src="../../images/promote.png" border="0" width="186" height="52" vspace="29" alt="Powered by NetworkEleven" /></a></td>
267 <td bgcolor="#003399" width="114" height="118" align="right"><img src="../../images/sprite.png" width="114" height="118" alt="" /></td>
268 <td bgcolor="#003399" width="114" height="118" align="right"><a href="http://www.imagemagick.net"><img src="../../images/logo.png" width="114" height="118" border="0" alt="ImageMagick logo" /></a></td>
269 </tr></tbody></table>
270 <table align="left" border="0" cellpadding="2" cellspacing="2" summary="Navigation buttons" width="20%">
271 <tr>
272 <td>
273 <form target="_self" action="../../index.html"><input type="submit" title="ImageMagick Home" value=" Home" style="background-color: #1947A3; background-image:url('../../../images/background.gif'); color:#fbc713; font-weight:bold"></form></td>
274 <td>
275 <form target="_self" action="../../www/apis.html"><input type="submit" title="ImageMagick API" value=" API " style="background-color: #1947A3; background-image:url('../../../images/background.gif'); color:#fbc713; font-weight:bold"></form></td>
276 <td>
277 <form target="_self" action="../../www/download.html"><input type="submit" title="ImageMagick Download" value="Download" style="background-color: #1947A3; background-image:url('../../../images/background.gif'); color:#fbc713; font-weight:bold"></form></td></tr></table>
278 <div align="right" style="margin-top:3px; padding-right:4px">
279 <form action="http://studio.imagemagick.org/Sage/scripts/Sage.cgi"><input type="TEXT" name="query" size="32" maxlength="255"> <input type="SUBMIT" name="sa" value="Search" style="background-color: #1947A3; background-image:url('../../../images/background.gif'); bgcolor:#003399; color:#fbc713; font-weight:bold"></form></div>
280 <table align="left" border="0" cellpadding="10" cellspacing="0" style="margin-top:-17px" width="100%">
281 <tr>
282 <td>
283 |;
284     s|</body>|
285 <HR>
286
287 <a href="#top"><img src="../../../images/top.gif" border=0 width="35" height="46" align="right" alt="Top of page"></a>
288 <form action="http://studio.imagemagick.org/magick/" style="margin-top:5px">
289 <input type="submit" title="Help!" value="Help!" style="background-image:url('../../../images/background.gif'); color:#fbc713; font-weight:bold">
290   <small>&quot;Image manipulation software that works like magick&quot;</small>
291 </form></td>
292 </tr></table>
293
294 </body>
295 |;
296     s|<FONT SIZE=-1>||g;
297     s|</FONT>||g;
298
299     s|<H2>|<H3>|g;
300     s|</H2>|</H3>|g;
301
302     s|<H1>|<H2>|g;
303     s|</H1>|</H2>|g;
304
305     s|<DT>|<DD><P></P><DT>|g;
306     s|<DL>|<DL><DT><DD><DL>|g;
307     s|</DL>|</DL></DL>|g;
308     s|<dd>|<DD>|g;
309     s|<p>|<P>|g;
310     s|</p>|</P>|g;
311     s|</LI>||g;
312     s|>o |>|g;
313     s|unsignedint|unsigned int|g;
314     print( OUT $_ );
315   }
316   close( TMP );
317   close( IN );
318 }
319
320 #
321 # Pre-process file into intermediate form
322 #
323 # Initializes globals:
324 #
325 #  @functions   - Function names
326 #  %synopsis    - Function synopsis
327 #
328 sub pre_format {
329   my($infile, $tmpfile) = @_;
330
331   my $inpara = 0;       # Set to 1 if in paragraph
332   my $inlist = 0;       # Set to 1 if in list-item paragraph
333
334   # Open C source file
335   open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
336
337   # Open TMP file
338   open( TMP, ">$tmpfile" ) || die("Failed to open \"$tmpfile\" for write\n" );
339
340   undef @functions;
341   undef %synopsis;
342
343   # Skip past first form feed
344   while(<IN>) {
345     last if m/\014/;
346   }
347
348 LINE:
349   while(<IN>) {
350     if (m/^\+/) {
351       while(<IN>) {
352         last unless m/^%/;
353       }
354       next;
355     }
356     next unless m/^%/ ;
357     chop;
358
359     # Extract and save function title
360     if (m/^%\s+((\w )+)\s+%/) {
361       ($ftitle = $1) =~ s/ //g;
362       push(@functions, $ftitle);
363       print( TMP "===$ftitle\n" );
364       next;
365     }
366
367     # Zap text we don't want
368     next if ( m/^%.+%/ );       # "%*%
369     s/^%\s{0,2}//;
370
371     # Extract and save synopsis info
372     if (m /\(\)/ ) {
373       # nothing
374       ;
375     }
376     elsif ( m/${ftitle}\(.*\)$/ ) {
377       s/,/ , /g;
378       s/\(/ ( /g;
379       s/\)/ ) /g;
380       s/\*/ * /g;
381       s/\s+/ /g;
382
383       s/\(\s+\*/(*/g;
384       s/ ,/,/g;
385       s/ \(/(/g;
386       s/\) /)/g;
387       s/ \* / */g;
388
389       s/^\s*//;
390       $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
391       print ( TMP " " . $synopsis{$ftitle} . "\n" );
392       next LINE;
393      }
394      elsif ( m/${ftitle}\(.*/ ) {
395       $synopsis{$ftitle} = $_;
396       do {
397         $_ = <IN>;
398         chop;
399         # Zap text we don't want
400         next if m/^%.+%/;       # "%*%
401         s/^%\s{0,2}//;
402         $synopsis{$ftitle} .= $_;
403       } until m/^\s*$/;
404       $_ = $synopsis{$ftitle};
405
406       s/,/ , /g;
407       s/\(/ ( /g;
408       s/\)/ ) /g;
409       s/\*/ * /g;
410       s/\s+/ /g;
411
412       s/\(\s+\*/(*/g;
413       s/ ,/,/g;
414       s/ \(/(/g;
415       s/\) /)/g;
416       s/ \* / */g;
417
418       s/^\s*//;
419       $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
420       print ( TMP " " . $synopsis{$ftitle} . "\n" );
421       next LINE;
422     }
423
424   # Keep track of paragraphing
425   if( ! m/^$/ ) {
426     if ( $inpara == 0 ) {
427       $inpara = 1;      # Start of paragraph
428       $para = "$_";     # Start paragraph string
429     } else {
430       # Inside paragraph
431       $para .= " $_";   # Add line to paragraph
432     }
433   }
434   # Keep track of list items so they can
435   # be wrapped as a paragraph
436   if( m/^\s+(o[^:]+:|o|[0-9]\.)\s(.*)/ ) {
437     $inlist = 1;
438   }
439
440   if ( $inpara == 1 ) {
441     if( $para =~ m/^\s+\S+/ && ! $inlist ) {
442       # Lines that start with a space shouldn't be munged
443       $inpara = 0;      # End of paragraph
444       $inlist = 0;
445       $para .= "";      # Terminate paragraph
446       print( TMP "$para\n" );
447     }
448     elsif( m/^$/ ) {
449       # End of paragraph
450       $inpara = 0;      # End of paragraph
451       $inlist = 0;
452       $para .= "";      # Terminate paragraph
453       $para =~ s/^\s+//g;               # Eliminate any leading space
454       $para =~ s/\s+/ /g;               # Canonicalize whitespace
455       $para =~ s/ $//;          # Trim final space
456       $para =~ s/([a-zA-Z0-9][.!?][)'"]*) /$1  /g; #' Fix sentance ends
457                   print( TMP "\n$para\n\n" );
458                 }
459     }
460   }
461
462   close( TMP );
463   close( IN );
464 }
465
466 #
467 # Second pass
468 # Process into formatted form
469 #
470 sub format_to_pod {
471     my($infile, $outfile) = @_;
472
473     my $func;
474
475     my $inlist = 0;             # Set to one if in indented list
476
477     # Open input file
478     open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
479
480     # Open output file
481     open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
482
483     # Name field
484     print( OUT head1("NAME") );
485     if (!defined($whatis{$base})) {
486       print("Whatis definition missing for \"$base\"!\n");
487       print( OUT "${base} - Unknown\n\n" );
488     } else {
489       print( OUT "${base} - $whatis{$base}\n\n" );
490     }
491
492     # Synopsis field (function signatures)
493     print( OUT head1("SYNOPSIS") );
494     foreach $func (sort( @functions )) {
495       if (defined $synopsis{$func} ) {
496         $_ = $synopsis{$func};
497         s/$func/ B<$func>/;
498         s/^\s*//;
499         my $synopsis = $_;
500         print( OUT $synopsis, "\n\n" );
501       }
502     }
503
504     # Description field
505     print( OUT head1("FUNCTION DESCRIPTIONS") );
506
507     while(<IN>){
508         chop;
509         next if m/^$/;
510
511         # Match list element
512         if( m/^(o[^:]+:|o|[0-9]\.?)\s(.*)/ ) {
513             my $bullet = $1;
514             my $bullet_text = $2;
515
516             print( OUT startlist() ) unless $inlist;
517             $inlist = 1;
518             print( OUT item($bullet), "$bullet_text\n\n" );
519             next;
520         } else {
521             print( OUT endlist() ) if $inlist;
522             $inlist = 0;
523         }
524
525         # Match synopsis item
526         if( defined $func && m/$func\s*\(.*\)/ ) {
527           # Split all words with spaces to aid with tokenization
528           s/,/ , /g;
529           s/\(/ ( /g;
530           s/\)/ ) /g;
531           s/\*/ * /g;
532
533           my $html = '';
534
535           # Replace tokens matching keywords with HTML links.
536 TOKEN:    foreach $token ( split(' ', $_ ) ) {
537             foreach $keyword ( %keywords ) {
538               if ( $token eq $keyword ) {
539                 $html .= linked( $keyword, $keywords{$keyword} );
540                 $html .= " ";
541                 next TOKEN;
542               }
543             }
544             $html .= "$token ";
545           }
546           $_ = $html;
547           # Remove excess spaces
548           s/\s+/ /g;
549           s/ ,/,/g;
550           s/\* /*/g;
551           s/\)\s*\;/);/;
552           s/^\s*//;
553           s/ \( *\)/\(\)/;
554
555           # This is very poor because text is output specifically
556           # for HTML so the text isn't output at all for other target
557           # formats.
558           print( OUT html("<blockquote>$_</blockquote>") );
559             next;
560         }
561
562         # Match function title
563         if( m/===([a-zA-Z0-9]+)/ ) {
564             $func = $1;
565             print( OUT head2($func) );
566             next;
567         }
568
569         print( OUT "\n") if /^[^ ]/;
570         print( OUT "$_\n") ;
571         print( OUT "\n") if /^[^ ]/;
572     }
573
574     close( OUT );
575     close( IN );
576 }
577
578 #
579 # Return level 1 heading
580 # Similar to: <H1>heading</H1>
581 #
582 sub head1 {
583     my($heading) = @_;
584     return( "=head1 $heading\n\n" );
585 }
586
587 #
588 # Return level 2 heading
589 # Similar to: <H2>heading</H2>
590 #
591 sub head2 {
592     my($heading) = @_;
593     return( "=head2 $heading\n\n" );
594 }
595
596
597 #
598 # Return item
599 # Simlar to: <I>
600 #
601 sub item {
602     my($item) = @_;
603     return( "=item $item\n\n" );
604 }
605
606
607 #
608 # Start list
609 # Similar to: <UL>
610 #
611 sub startlist {
612     return( "=over 4\n\n" )
613 }
614
615 #
616 # End list
617 # Similar to: </UL>
618 #
619 sub endlist {
620     return( "=back\n\n" );
621 }
622
623 #
624 # Preformatted text
625 # Similar to <PRE></PRE>
626 #
627 sub formated {
628     my($text) = @_;
629     return( " $text\n\n" );
630 }
631
632 #
633 # Raw HTML paragraph
634 #
635 sub html {
636   my($html) = @_;
637   return return( "=for html $html\n\n" );
638 }
639
640 #
641 # HTML Link
642 # Similar to: <A HREF="url">description</A>
643 #
644 sub linked {
645   local($description, $url) = @_;
646   return( "<A HREF=\"" . $url . "\">" . $description . "</A>" );
647 }