~ubuntu-branches/ubuntu/trusty/graphicsmagick/trusty-proposed

« back to all changes in this revision

Viewing changes to scripts/format_c_api_docs

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2009-05-07 20:09:28 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090507200928-5rb3jyvrsi9x3zfl
Tags: 1.3.5-5
* debian/control: Update Conflicts/Replaces of -dev-compat package to
  follow libmagick-dev package split. Closes: #526482
* magick/GraphicsMagick-config.{in,1}: Do not expose compiler options
  used to build the library itself via GraphicsMagick-config. Only
  provide options that are actually useful to depending applications.
  Adjust documentation accordingly. Closes: #523596

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
         'composite.c',
36
 
         'constitute.c',
37
 
         'decorate.c',
38
 
         'deprecate.c',
39
 
         'render.c',
40
 
         'draw.c',
41
 
         'display.c',
42
 
         'effect.c',
43
 
         'enhance.c',
44
 
         'error.c',
45
 
         'fx.c',
46
 
         'image.c',
47
 
         'list.c',
48
 
         'magick.c',
49
 
         'memory.c',
50
 
         'monitor.c',
51
 
         'montage.c',
52
 
         'paint.c',
53
 
         'profile.c',
54
 
         'quantize.c',
55
 
         'registry.c',
56
 
         'resource.c',
57
 
         'segment.c',
58
 
         'shear.c',
59
 
         'signature.c',
60
 
         'stream.c',
61
 
         'transform.c',
62
 
         'resize.c',
63
 
         'widget.c');
64
 
 
65
 
$tmpname_pre_format = "/tmp/fmtdocs_pre.$$";
66
 
$tmpname_pod = "/tmp/fmtdocs_pod.$$";
67
 
$tmpname_html = "/tmp/fmtdocs_html.$$";
68
 
 
69
 
#@srcs = ('draw.c');
70
 
 
71
 
#
72
 
# What is for source files
73
 
#
74
 
%whatis =
75
 
(
76
 
 'animate',     'Interactively animate an image sequence',
77
 
 'annotate',    'Annotate an image with text',
78
 
 'attribute',   'Access key,value image attributes',
79
 
 'blob',        'Read or write formatted images in memory (BLOBs)',
80
 
 'color',       'Color related functions',
81
 
 'constitute',  'Read or write an image',
82
 
 'composite',   'Merge image pixels using a specified algorithm',
83
 
 'decorate',    'Add decorative frames and borders',
84
 
 'deprecate',   'Methods which should no longer be used',
85
 
 'display',     'Interactively display and edit an image',
86
 
 'render',      'Low-level methods to draw on an image',
87
 
 'draw',        'User-friendly methods to draw on an image',
88
 
 'effect',      'Image effects methods',
89
 
 'fx',          'Image special effects methods',
90
 
 'enhance',     'Methods to enhance or adjust an image',
91
 
 'error',       'Error reporting methods',
92
 
 'image',       'Miscellaneous image methods',
93
 
 'list',        'Image list support',
94
 
 'cache',       'Low-level access to image pixels',
95
 
 'cache_view',  'Low-level access to image pixels with multiple views',
96
 
 'magick',      'Image format support interfaces',
97
 
 'memory',      'Memory allocation/deallocation functions',
98
 
 'monitor',     'Progress monitor support',
99
 
 'montage',     'Create a thumbnail image mosaic',
100
 
 'paint',       'Methods to fill image pixel regions',
101
 
 'profile',     'Manipulate embedded profiles',
102
 
 'quantize',    'Reduce the number of colors in an image',
103
 
 'registry',    'In-memory image registration interface',
104
 
 'resource',    'Set resource consumption limits (e.g. memory)',
105
 
 'segment',     'Segment and image with thresholding using the fuzzy c-means method',
106
 
 'shear',       'Rotate image, shear image, or apply a 2D affine transformation',
107
 
 'signature',   'Add a digital signature to the image',
108
 
 'stream',      'Low-level image pixel FIFO (tap into encode/decode pixel stream)',
109
 
 'transform',   'Crop, flip, flop, roll, coalesce, etc.',
110
 
 'resize',      'Resize an image',
111
 
 'widget',      'X11 Widgets'
112
 
);
113
 
 
114
 
#
115
 
# Key words to replace with HTML links
116
 
#
117
 
my %keywords =
118
 
  (
119
 
   AffineMatrix         => 'types.html#AffineMatrix',
120
 
   BlobInfo             => 'types.html#BlobInfo',
121
 
   Cache                => 'types.html#Cache',
122
 
   ChannelType          => 'types.html#ChannelType',
123
 
   ChromaticityInfo     => 'types.html#ChromaticityInfo',
124
 
   ClassType            => 'types.html#ClassType',
125
 
   ClipPathUnits        => 'types.html#ClipPathUnits',
126
 
   ColorPacket          => 'types.html#ColorPacket',
127
 
   ColorspaceType       => 'types.html#ColorspaceType',
128
 
   ComplianceType       => 'types.html#ComplianceType',
129
 
   CompositeOperator    => 'types.html#CompositeOperator',
130
 
   CompressionType      => 'types.html#CompressionType',
131
 
   DecorationType       => 'types.html#DecorationType',
132
 
   DrawContext          => 'types.html#DrawContext',
133
 
   DrawInfo             => 'types.html#DrawInfo',
134
 
   ErrorHandler         => 'types.html#ErrorHandler',
135
 
   ExceptionInfo        => 'types.html#ExceptionInfo',
136
 
   ExceptionType        => 'types.html#ExceptionType',
137
 
   FillRule             => 'types.html#FillRule',
138
 
   FilterTypes          => 'types.html#FilterTypes',
139
 
   FrameInfo            => 'types.html#FrameInfo',
140
 
   GravityType          => 'types.html#GravityType',
141
 
   Image                => 'types.html#Image',
142
 
   ImageInfo            => 'types.html#ImageInfo',
143
 
   ImageType            => 'types.html#ImageType',
144
 
   InterlaceType        => 'types.html#InterlaceType',
145
 
   LayerType            => 'types.html#LayerType',
146
 
   MagickInfo           => 'types.html#MagickInfo',
147
 
   MonitorHandler       => 'types.html#MonitorHandler',
148
 
   MontageInfo          => 'types.html#MontageInfo',
149
 
   NoiseType            => 'types.html#NoiseType',
150
 
   PaintMethod          => 'types.html#PaintMethod',
151
 
   PixelPacket          => 'types.html#PixelPacket',
152
 
   PointInfo            => 'types.html#PointInfo',
153
 
   ProfileInfo          => 'types.html#ProfileInfo',
154
 
   QuantizeInfo         => 'types.html#QuantizeInfo',
155
 
   Quantum              => 'types.html#Quantum',
156
 
   QuantumType          => 'types.html#QuantumType',
157
 
   RectangleInfo        => 'types.html#RectangleInfo',
158
 
   RegistryType         => 'types.html#RegistryType',
159
 
   RenderingIntent      => 'types.html#RenderingIntent',
160
 
   ResolutionType       => 'types.html#ResolutionType',
161
 
   ResourceType         => 'types.html#ResourceType',
162
 
   SegmentInfo          => 'types.html#SegmentInfo',
163
 
   SignatureInfo        => 'types.html#SignatureInfo',
164
 
   StorageType          => 'types.html#StorageType',
165
 
   StreamHandler        => 'types.html#StreamHandler',
166
 
   StretchType          => 'types.html#StretchType',
167
 
   StyleType            => 'types.html#StyleType',
168
 
   TypeMetric           => 'types.html#TypeMetric',
169
 
   ViewInfo             => 'types.html#ViewInfo',
170
 
   VirtualPixelMethod   => 'types.html#VirtualPixelMethod',
171
 
   XResourceInfo        => 'types.html#XResourceInfo',
172
 
);
173
 
 
174
 
 
175
 
foreach $src (@srcs) {
176
 
 
177
 
  my($out,$command);
178
 
 
179
 
  # Compute POD name
180
 
  ($base = $src) =~ s/\.[^\.]*$//g;
181
 
 
182
 
  $out = "${base}.${opt_format}";
183
 
  if ("${opt_outdir}" ne "") {
184
 
    $out = "${opt_outdir}/${base}.${opt_format}";
185
 
  }
186
 
 
187
 
  if ("${opt_srcdir}" ne "") {
188
 
    $src = "${opt_srcdir}/${src}";
189
 
  }
190
 
 
191
 
  $command='pod2html -netscape';
192
 
  if ( $opt_format eq 'html' ) {
193
 
    $command='pod2html -netscape';
194
 
  } elsif ( $opt_format eq 'latex' ) {
195
 
    $command='pod2latex';
196
 
  } elsif ( $opt_format eq 'man' ) {
197
 
    $command='pod2man';
198
 
  } elsif ( $opt_format eq 'text' ) {
199
 
    $command='pod2text';
200
 
  } elsif ( $opt_format eq 'pod' ) {
201
 
    $command='cat';
202
 
  }
203
 
 
204
 
  print( "Processing $src -> $out\n" );
205
 
 
206
 
  pre_format($src, $tmpname_pre_format);                # Make easily parsed
207
 
  format_to_pod($tmpname_pre_format, $tmpname_pod);     # Format to pod.
208
 
 
209
 
  if ( $opt_format eq 'html' ) {
210
 
    system("$command $tmpname_pod > \"$tmpname_html\"");
211
 
    reformat_html($tmpname_html,$out);
212
 
  } else {
213
 
    system("$command $tmpname_pod > \"$out\"");
214
 
  }
215
 
  unlink($tmpname_pre_format);
216
 
  unlink($tmpname_pod);
217
 
  unlink($tmpname_html);
218
 
}
219
 
 
220
 
#unlink($tmpname_pre_format);
221
 
exit(0);
222
 
 
223
 
#
224
 
# Reformat pod2html-generated HTML into nicer form.
225
 
#
226
 
sub reformat_html {
227
 
  my($infile, $outfile) = @_;
228
 
 
229
 
  open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
230
 
  open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
231
 
 
232
 
 INPUT:
233
 
  while(<IN>) {
234
 
    s|<HTML>|<\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"<HTML>|;
235
 
    s|<HTML>| "http://www.w3.org/TR/html4/loose.dtd"><HTML>|;
236
 
    s|<HEAD>|<HEAD>
237
 
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
238
 
<STYLE>
239
 
<!--
240
 
\@page { size: 8.5in 11in }
241
 
TD P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
242
 
P { color: #000000; font-family: "Verdana", "Arial", "Helvetica", sans-serif; font-size: 12pt }
243
 
H2 { color: #000000 }
244
 
A:link { color: #0085c0 }
245
 
A:visited { color: #800080 }
246
 
-->
247
 
</STYLE>
248
 
|;
249
 
    s|<BODY>|<BODY LANG="en-US" TEXT="#000000" LINK="#0085c0" VLINK="#800080" BGCOLOR="#ffffff">|;
250
 
    s|<FONT SIZE=-1>||g;
251
 
    s|</FONT>||g;
252
 
 
253
 
    s|<H2>|<H3>|g;
254
 
    s|</H2>|</H3>|g;
255
 
 
256
 
    s|<H1>|<H2>|g;
257
 
    s|</H1>|</H2>|g;
258
 
 
259
 
    s|<DT>|<DD><P></P><DT>|g;
260
 
    s|<DL>|<DL><DT><DD><DL>|g;
261
 
    s|</DL>|</DL></DL>|g;
262
 
    s|<dd>|<DD>|g;
263
 
    s|<p>|<P>|g;
264
 
    s|</p>|</P>|g;
265
 
    s|</LI>||g;
266
 
    s|>o |>|g;
267
 
    s|unsignedint|unsigned int|g;
268
 
    print( OUT $_ );
269
 
  }
270
 
  close( TMP );
271
 
  close( IN );
272
 
}
273
 
 
274
 
#
275
 
# Pre-process file into intermediate form
276
 
#
277
 
# Initializes globals:
278
 
#
279
 
#  @functions   - Function names
280
 
#  %synopsis    - Function synopsis
281
 
#
282
 
sub pre_format {
283
 
  my($infile, $tmpfile) = @_;
284
 
 
285
 
  my $inpara = 0;       # Set to 1 if in paragraph
286
 
  my $inlist = 0;       # Set to 1 if in list-item paragraph
287
 
 
288
 
  # Open C source file
289
 
  open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
290
 
 
291
 
  # Open TMP file
292
 
  open( TMP, ">$tmpfile" ) || die("Failed to open \"$tmpfile\" for write\n" );
293
 
 
294
 
  undef @functions;
295
 
  undef %synopsis;
296
 
 
297
 
  # Skip past first form feed
298
 
  while(<IN>) {
299
 
    last if m/\014/;
300
 
  }
301
 
 
302
 
LINE:
303
 
  while(<IN>) {
304
 
    if (m/^\+/) {
305
 
      while(<IN>) {
306
 
        last unless m/^%/;
307
 
      }
308
 
      next;
309
 
    }
310
 
    next unless m/^%/ ;
311
 
    chop;
312
 
 
313
 
    # Extract and save function title
314
 
    if (m/^%\s+((\w )+)\s+%/) {
315
 
      ($ftitle = $1) =~ s/ //g;
316
 
      push(@functions, $ftitle);
317
 
      print( TMP "===$ftitle\n" );
318
 
      next;
319
 
    }
320
 
 
321
 
    # Zap text we don't want
322
 
    next if ( m/^%.+%/ );       # "%*%
323
 
    s/^%\s{0,2}//;
324
 
 
325
 
    # Extract and save synopsis info
326
 
    if (m /\(\)/ ) {
327
 
      # nothing
328
 
      ;
329
 
    }
330
 
    elsif ( m/${ftitle}\(.*\)$/ ) {
331
 
      s/,/ , /g;
332
 
      s/\(/ ( /g;
333
 
      s/\)/ ) /g;
334
 
      s/\*/ * /g;
335
 
      s/\s+/ /g;
336
 
 
337
 
      s/\(\s+\*/(*/g;
338
 
      s/ ,/,/g;
339
 
      s/ \(/(/g;
340
 
      s/\) /)/g;
341
 
      s/ \* / */g;
342
 
 
343
 
      s/^\s*//;
344
 
      $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
345
 
      print ( TMP " " . $synopsis{$ftitle} . "\n" );
346
 
      next LINE;
347
 
     }
348
 
     elsif ( m/${ftitle}\(.*/ ) {
349
 
      $synopsis{$ftitle} = $_;
350
 
      do {
351
 
        $_ = <IN>;
352
 
        chop;
353
 
        # Zap text we don't want
354
 
        next if m/^%.+%/;       # "%*%
355
 
        s/^%\s{0,2}//;
356
 
        $synopsis{$ftitle} .= $_;
357
 
      } until m/^\s*$/;
358
 
      $_ = $synopsis{$ftitle};
359
 
 
360
 
      s/,/ , /g;
361
 
      s/\(/ ( /g;
362
 
      s/\)/ ) /g;
363
 
      s/\*/ * /g;
364
 
      s/\s+/ /g;
365
 
 
366
 
      s/\(\s+\*/(*/g;
367
 
      s/ ,/,/g;
368
 
      s/ \(/(/g;
369
 
      s/\) /)/g;
370
 
      s/ \* / */g;
371
 
 
372
 
      s/^\s*//;
373
 
      $synopsis{$ftitle} = $_ . ';'; # Append semi-colon, prototype style
374
 
      print ( TMP " " . $synopsis{$ftitle} . "\n" );
375
 
      next LINE;
376
 
    }
377
 
 
378
 
  # Keep track of paragraphing
379
 
  if( ! m/^$/ ) {
380
 
    if ( $inpara == 0 ) {
381
 
      $inpara = 1;      # Start of paragraph
382
 
      $para = "$_";     # Start paragraph string
383
 
    } else {
384
 
      # Inside paragraph
385
 
      $para .= " $_";   # Add line to paragraph
386
 
    }
387
 
  }
388
 
  # Keep track of list items so they can
389
 
  # be wrapped as a paragraph
390
 
  if( m/^\s+(o[^:]+:|o|[0-9]\.)\s(.*)/ ) {
391
 
    $inlist = 1;
392
 
  }
393
 
 
394
 
  if ( $inpara == 1 ) {
395
 
    if( $para =~ m/^\s+\S+/ && ! $inlist ) {
396
 
      # Lines that start with a space shouldn't be munged
397
 
      $inpara = 0;      # End of paragraph
398
 
      $inlist = 0;
399
 
      $para .= "";      # Terminate paragraph
400
 
      print( TMP "$para\n" );
401
 
    }
402
 
    elsif( m/^$/ ) {
403
 
      # End of paragraph
404
 
      $inpara = 0;      # End of paragraph
405
 
      $inlist = 0;
406
 
      $para .= "";      # Terminate paragraph
407
 
      $para =~ s/^\s+//g;               # Eliminate any leading space
408
 
      $para =~ s/\s+/ /g;               # Canonicalize whitespace
409
 
      $para =~ s/ $//;          # Trim final space
410
 
      $para =~ s/([a-zA-Z0-9][.!?][)'"]*) /$1  /g; #' Fix sentance ends
411
 
                  print( TMP "\n$para\n\n" );
412
 
                }
413
 
    }
414
 
  }
415
 
 
416
 
  close( TMP );
417
 
  close( IN );
418
 
}
419
 
 
420
 
#
421
 
# Second pass
422
 
# Process into formatted form
423
 
#
424
 
sub format_to_pod {
425
 
    my($infile, $outfile) = @_;
426
 
 
427
 
    my $func;
428
 
 
429
 
    my $inlist = 0;             # Set to one if in indented list
430
 
 
431
 
    # Open input file
432
 
    open( IN, "<$infile" ) || die("Failed to open \"$infile\" for read\n" );
433
 
 
434
 
    # Open output file
435
 
    open( OUT, ">$outfile" ) || die("Failed to open \"$outfile\" for write\n" );
436
 
 
437
 
    # Name field
438
 
    print( OUT head1("NAME") );
439
 
    if (!defined($whatis{$base})) {
440
 
      print("Whatis definition missing for \"$base\"!\n");
441
 
      print( OUT "${base} - Unknown\n\n" );
442
 
    } else {
443
 
      print( OUT "${base} - $whatis{$base}\n\n" );
444
 
    }
445
 
 
446
 
    # Synopsis field (function signatures)
447
 
    print( OUT head1("SYNOPSIS") );
448
 
    foreach $func (sort( @functions )) {
449
 
      if (defined $synopsis{$func} ) {
450
 
        $_ = $synopsis{$func};
451
 
        s/$func/ B<$func>/;
452
 
        s/^\s*//;
453
 
        my $synopsis = $_;
454
 
        print( OUT $synopsis, "\n\n" );
455
 
      }
456
 
    }
457
 
 
458
 
    # Description field
459
 
    print( OUT head1("FUNCTION DESCRIPTIONS") );
460
 
 
461
 
    while(<IN>){
462
 
        chop;
463
 
        next if m/^$/;
464
 
 
465
 
        # Match list element
466
 
        if( m/^(o[^:]+:|o|[0-9]\.?)\s(.*)/ ) {
467
 
            my $bullet = $1;
468
 
            my $bullet_text = $2;
469
 
 
470
 
            print( OUT startlist() ) unless $inlist;
471
 
            $inlist = 1;
472
 
            print( OUT item($bullet), "$bullet_text\n\n" );
473
 
            next;
474
 
        } else {
475
 
            print( OUT endlist() ) if $inlist;
476
 
            $inlist = 0;
477
 
        }
478
 
 
479
 
        # Match synopsis item
480
 
        if( defined $func && m/$func\s*\(.*\)/ ) {
481
 
          # Split all words with spaces to aid with tokenization
482
 
          s/,/ , /g;
483
 
          s/\(/ ( /g;
484
 
          s/\)/ ) /g;
485
 
          s/\*/ * /g;
486
 
 
487
 
          my $html = '';
488
 
 
489
 
          # Replace tokens matching keywords with HTML links.
490
 
TOKEN:    foreach $token ( split(' ', $_ ) ) {
491
 
            foreach $keyword ( %keywords ) {
492
 
              if ( $token eq $keyword ) {
493
 
                $html .= linked( $keyword, $keywords{$keyword} );
494
 
                $html .= " ";
495
 
                next TOKEN;
496
 
              }
497
 
            }
498
 
            $html .= "$token ";
499
 
          }
500
 
          $_ = $html;
501
 
          # Remove excess spaces
502
 
          s/\s+/ /g;
503
 
          s/ ,/,/g;
504
 
          s/\* /*/g;
505
 
          s/\)\s*\;/);/;
506
 
          s/^\s*//;
507
 
          s/ \( *\)/\(\)/;
508
 
 
509
 
          # This is very poor because text is output specifically
510
 
          # for HTML so the text isn't output at all for other target
511
 
          # formats.
512
 
          print( OUT html("<blockquote>$_</blockquote>") );
513
 
            next;
514
 
        }
515
 
 
516
 
        # Match function title
517
 
        if( m/===([a-zA-Z0-9]+)/ ) {
518
 
            $func = $1;
519
 
            print( OUT head2($func) );
520
 
            next;
521
 
        }
522
 
 
523
 
        print( OUT "\n") if /^[^ ]/;
524
 
        print( OUT "$_\n") ;
525
 
        print( OUT "\n") if /^[^ ]/;
526
 
    }
527
 
 
528
 
    close( OUT );
529
 
    close( IN );
530
 
}
531
 
 
532
 
#
533
 
# Return level 1 heading
534
 
# Similar to: <H1>heading</H1>
535
 
#
536
 
sub head1 {
537
 
    my($heading) = @_;
538
 
    return( "=head1 $heading\n\n" );
539
 
}
540
 
 
541
 
#
542
 
# Return level 2 heading
543
 
# Similar to: <H2>heading</H2>
544
 
#
545
 
sub head2 {
546
 
    my($heading) = @_;
547
 
    return( "=head2 $heading\n\n" );
548
 
}
549
 
 
550
 
 
551
 
#
552
 
# Return item
553
 
# Simlar to: <I>
554
 
#
555
 
sub item {
556
 
    my($item) = @_;
557
 
    return( "=item $item\n\n" );
558
 
}
559
 
 
560
 
 
561
 
#
562
 
# Start list
563
 
# Similar to: <UL>
564
 
#
565
 
sub startlist {
566
 
    return( "=over 4\n\n" )
567
 
}
568
 
 
569
 
#
570
 
# End list
571
 
# Similar to: </UL>
572
 
#
573
 
sub endlist {
574
 
    return( "=back\n\n" );
575
 
}
576
 
 
577
 
#
578
 
# Preformatted text
579
 
# Similar to <PRE></PRE>
580
 
#
581
 
sub formated {
582
 
    my($text) = @_;
583
 
    return( " $text\n\n" );
584
 
}
585
 
 
586
 
#
587
 
# Raw HTML paragraph
588
 
#
589
 
sub html {
590
 
  my($html) = @_;
591
 
  return return( "=for html $html\n\n" );
592
 
}
593
 
 
594
 
#
595
 
# HTML Link
596
 
# Similar to: <A HREF="url">description</A>
597
 
#
598
 
sub linked {
599
 
  local($description, $url) = @_;
600
 
  return( "<A HREF=\"" . $url . "\">" . $description . "</A>" );
601
 
}