3 # Format ImageMagick comments into POD-format or HTML format
5 # Produces *.pod or *.html files corresponding to *.c files
7 # Written by Bob Friesenhahn, April 1997
16 'format=s' => \$opt_format,
17 'srcdir=s' => \$opt_srcdir,
18 'outdir=s' => \$opt_outdir,
21 print("Usage: fmtdocs [-srcdir srcdir] [-outdir outdir] [-format format] \n");
70 $tmpname_pre_format = "/tmp/fmtdocs_pre.$$";
71 $tmpname_pod = "/tmp/fmtdocs_pod.$$";
72 $tmpname_html = "/tmp/fmtdocs_html.$$";
77 # What is for source files
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',
125 # Key words to replace with HTML links
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',
185 foreach $src (@srcs) {
190 ($base = $src) =~ s/\.[^\.]*$//g;
192 $out = "${base}.${opt_format}";
193 if ("${opt_outdir}" ne "") {
194 $out = "${opt_outdir}/${base}.${opt_format}";
197 if ("${opt_srcdir}" ne "") {
198 $src = "${opt_srcdir}/${src}";
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' ) {
208 } elsif ( $opt_format eq 'text' ) {
210 } elsif ( $opt_format eq 'pod' ) {
214 print( "Processing $src -> $out\n" );
216 pre_format($src, $tmpname_pre_format); # Make easily parsed
217 format_to_pod($tmpname_pre_format, $tmpname_pod); # Format to pod.
219 if ( $opt_format eq 'html' ) {
220 system("$command $tmpname_pod > \"$tmpname_html\"");
221 reformat_html($tmpname_html,$out);
223 system("$command $tmpname_pod > \"$out\"");
225 unlink($tmpname_pre_format);
226 unlink($tmpname_pod);
227 unlink($tmpname_html);
230 #unlink($tmpname_pre_format);
234 # Reformat pod2html-generated HTML into nicer form.
237 my($infile, $outfile) = @_;
239 open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
240 open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
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">|;
247 <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
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 }
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">
262 <table border="0" cellpadding="0" cellspacing="0" summary="Masthead" width="100%">
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%">
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>
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>
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%">
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>"Image manipulation software that works like magick"</small>
305 s|<DT>|<DD><P></P><DT>|g;
306 s|<DL>|<DL><DT><DD><DL>|g;
307 s|</DL>|</DL></DL>|g;
313 s|unsignedint|unsigned int|g;
321 # Pre-process file into intermediate form
323 # Initializes globals:
325 # @functions - Function names
326 # %synopsis - Function synopsis
329 my($infile, $tmpfile) = @_;
331 my $inpara = 0; # Set to 1 if in paragraph
332 my $inlist = 0; # Set to 1 if in list-item paragraph
335 open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
338 open( TMP, ">$tmpfile" ) || die("Failed to open \"$tmpfile\" for write\n" );
343 # Skip past first form feed
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" );
367 # Zap text we don't want
368 next if ( m/^%.+%/ ); # "%*%
371 # Extract and save synopsis info
376 elsif ( m/${ftitle}\(.*\)$/ ) {
390 $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
391 print ( TMP " " . $synopsis{$ftitle} . "\n" );
394 elsif ( m/${ftitle}\(.*/ ) {
395 $synopsis{$ftitle} = $_;
399 # Zap text we don't want
400 next if m/^%.+%/; # "%*%
402 $synopsis{$ftitle} .= $_;
404 $_ = $synopsis{$ftitle};
419 $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
420 print ( TMP " " . $synopsis{$ftitle} . "\n" );
424 # Keep track of paragraphing
426 if ( $inpara == 0 ) {
427 $inpara = 1; # Start of paragraph
428 $para = "$_"; # Start paragraph string
431 $para .= " $_"; # Add line to paragraph
434 # Keep track of list items so they can
435 # be wrapped as a paragraph
436 if( m/^\s+(o[^:]+:|o|[0-9]\.)\s(.*)/ ) {
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
445 $para .= ""; # Terminate paragraph
446 print( TMP "$para\n" );
450 $inpara = 0; # End of paragraph
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" );
468 # Process into formatted form
471 my($infile, $outfile) = @_;
475 my $inlist = 0; # Set to one if in indented list
478 open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
481 open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
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" );
489 print( OUT "${base} - $whatis{$base}\n\n" );
492 # Synopsis field (function signatures)
493 print( OUT head1("SYNOPSIS") );
494 foreach $func (sort( @functions )) {
495 if (defined $synopsis{$func} ) {
496 $_ = $synopsis{$func};
500 print( OUT $synopsis, "\n\n" );
505 print( OUT head1("FUNCTION DESCRIPTIONS") );
512 if( m/^(o[^:]+:|o|[0-9]\.?)\s(.*)/ ) {
514 my $bullet_text = $2;
516 print( OUT startlist() ) unless $inlist;
518 print( OUT item($bullet), "$bullet_text\n\n" );
521 print( OUT endlist() ) if $inlist;
525 # Match synopsis item
526 if( defined $func && m/$func\s*\(.*\)/ ) {
527 # Split all words with spaces to aid with tokenization
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} );
547 # Remove excess spaces
555 # This is very poor because text is output specifically
556 # for HTML so the text isn't output at all for other target
558 print( OUT html("<blockquote>$_</blockquote>") );
562 # Match function title
563 if( m/===([a-zA-Z0-9]+)/ ) {
565 print( OUT head2($func) );
569 print( OUT "\n") if /^[^ ]/;
571 print( OUT "\n") if /^[^ ]/;
579 # Return level 1 heading
580 # Similar to: <H1>heading</H1>
584 return( "=head1 $heading\n\n" );
588 # Return level 2 heading
589 # Similar to: <H2>heading</H2>
593 return( "=head2 $heading\n\n" );
603 return( "=item $item\n\n" );
612 return( "=over 4\n\n" )
620 return( "=back\n\n" );
625 # Similar to <PRE></PRE>
629 return( " $text\n\n" );
637 return return( "=for html $html\n\n" );
642 # Similar to: <A HREF="url">description</A>
645 local($description, $url) = @_;
646 return( "<A HREF=\"" . $url . "\">" . $description . "</A>" );