00001 package Doxygen::Item;
00002
00003 =head1 NAME
00004
00005 Doxygen::Item - Perl extension for generating Doxygen documentation
00006
00007 =head1 SYNOPSIS
00008
00009 Inherited by subclass:
00010
00011 use base qw(Doxygen::Filter);
00012
00013 =head1 ABSTRACT
00014
00015 Provides a root class for a source object for the Doxygen documentation tool.
00016 This class should be inherited by source-specific subclasses, which will in
00017 turn be used by the DoxyFilt.pl script, called by the Doxygen program to
00018 process source files other than C and C++.
00019
00020 A Doxygen::Item is an object that will be recognized by Doxygen when rendered
00021 as a combination of C/C++ source code and Doxygen-enabled comments.
00022 Known subclasses of Doxygen::Item include Doxygen::Item::Class,
00023 Doxygen::Item::Class and Doxygen::Item::Function.
00024
00025 =head1 DESCRIPTION
00026
00027 =head1 METHODS
00028
00029 =over
00030
00031 =cut
00032
00033 use 5.005; # just to pick something, but not really tested
00034 use strict;
00035 use warnings;
00036 use UNIVERSAL qw(can isa);
00037
00038 our $VERSION = '0.01';
00039
00040 ###########################################################################
00041 ###########################################################################
00042
00043 =item C<new($class, %fields)>
00044
00045 Generic constructor for Doxygen::Item interprets all arguments
00046 as a hash object and blesses a reference thereto, making it easy
00047 to set initial field values.
00048
00049 =cut
00050
00051 sub new # $class, %fields
00052 {
00053 my ($class, %fields) = @_;
00054
00055 $fields{_sort_}->{Class} = 'order'
00056 unless defined $fields{_sort_}->{Class};
00057
00058 $fields{_sort_}->{Function} = 'alpha'
00059 unless defined $fields{_sort_}->{Function};
00060
00061 bless \%fields, $class
00062 }
00063
00064 ###########################################################################
00065 ###########################################################################
00066
00067 =item C<massage($self, $source)>
00068
00069 Item-specific massage sequences.
00070
00071 =cut
00072
00073 sub massage # $self, $source
00074 {
00075 }
00076
00077 ###########################################################################
00078 ###########################################################################
00079
00080 =item C<generate($self, %flags)>
00081
00082 Generates output understandable by doxygen to standard output.
00083
00084 =cut
00085
00086 sub generate # $self, %flags
00087 {
00088 my $self = shift;
00089
00090 $_->generate(@_)
00091 for $self->items('class');
00092
00093 $_->generate(@_)
00094 for $self->items('function');
00095 }
00096
00097 ###########################################################################
00098
00099 =item C<genComment($self, %flags)>
00100
00101 Generates comment lines for the item.
00102
00103 =cut
00104
00105 sub genComment # $self, %flags
00106 {
00107 my $self = shift;
00108
00109 for my $which (qw(brief comment notes)) {
00110 my $text = $self->text($which);
00111
00112 next unless $text;
00113
00114 unless (isa($text, 'ARRAY')) {
00115 warn "*** $which items for $self not an array reference\n";
00116 next;
00117 }
00118
00119 genThing($_, @_, comment => 1, which => $which)
00120 for @$text;
00121 }
00122 }
00123
00124 ###########################################################################
00125
00126 =item C<genThing($thing, %flags)>
00127
00128 Generate a thing, which may be an object, an array reference, or a string.
00129
00130 When the thing is an object of type Doxygen::Item it is generated
00131 using the C<generate> method.
00132
00133 Recursive.
00134
00135 =cut
00136
00137 sub genThing # $thing, %flags
00138 {
00139 my $thing = shift;
00140
00141 return
00142 unless defined $thing;
00143
00144 if (isa($thing, 'Doxygen::Item') && ref($thing)) {
00145 $thing->generate(@_)
00146 unless $thing->{disabled};
00147 } elsif (isa($thing, 'ARRAY')) {
00148 # Wrapped in an array, strings not to be in comment chars:
00149 genThing($_ , @_) for @$thing;
00150 } else {
00151 # Should just be a string:
00152 my %flags = @_;
00153 my $indent = $flags{indent} || '';
00154
00155 if ($flags{comment}) {
00156 $indent .= ' * ';
00157 $indent .= $flags{over} if $flags{over};
00158 $indent .= ' ';
00159 }
00160
00161 return
00162 unless defined $thing;
00163
00164 print $indent, $thing;
00165 print "\n"
00166 unless $thing =~ /\n$/;
00167 }
00168 }
00169
00170 ###########################################################################
00171 ###########################################################################
00172
00173 =item C<image($self)>
00174
00175 Return image for item.
00176
00177 =cut
00178
00179 sub image # $self
00180 {
00181 $_[0]->{name} || '<|' . ref($_[0]) . '|>'
00182 }
00183
00184 ###########################################################################
00185 ###########################################################################
00186
00187 =item C<itemSet($self, $which, $entity [ , $name ])>
00188
00189 Set a named item of the specified type (C<$which>).
00190
00191 =cut
00192
00193 sub itemSet # $self, $which, $entity [ , $name ]
00194 {
00195 my $self = shift;
00196 my $which = shift;
00197 my $entity = shift;
00198 my $name = shift || $entity->{name};
00199 my $orig = $self->{which}->{lookup}->{$name};
00200
00201 # print STDERR "itemSet($which, $entity, $name)\n";
00202
00203 if ($orig) {
00204 warn "*** $which $name defined twice, using last definition\n";
00205 $self->{$which}->{order} =
00206 grep { $_ != $name } @{$self->{$which}->{order}};
00207 }
00208
00209 push @{$self->{$which}->{order}}, $name;
00210 $self->{$which}->{lookup}->{$name} = $entity;
00211
00212 # print STDERR "itemSet done\n";
00213
00214 $orig || $entity
00215 }
00216
00217 ###########################################################################
00218
00219 =item C<item($self, $which, $name)>
00220
00221 Return a named item of the specified type (C<$which>).
00222
00223 =cut
00224
00225 sub item # $self, $which, $name
00226 {
00227 $_[0]->{$_[1]}->{lookup}->{$_[2]}
00228 }
00229
00230 ###########################################################################
00231
00232 =item C<items($self, $which)>
00233
00234 Returns all named items of a specified type.
00235
00236 =cut
00237
00238 sub items # $self, $which
00239 {
00240 map { $_[0]->{$_[1]}->{lookup}->{$_} } @{$_[0]->{$_[1]}->{order}}
00241 }
00242
00243 ###########################################################################
00244 ###########################################################################
00245
00246 =item C<text($self [ , $which ])>
00247
00248 Returns array reference of array representing named text block.
00249
00250 Text blocks might include C<brief>, C<comment>, C<text>.
00251 If no text block name (C<$which>) is specified,
00252 the default C<'text'> block is used.
00253
00254 =cut
00255
00256 sub text # $self [ , $which ]
00257 {
00258 my $self = shift;
00259 my $which = shift || 'text';
00260
00261 $self->{text}->{$which} || [ ]
00262 }
00263
00264 ###########################################################################
00265
00266 =item C<textAppend($self, $which, @stuff)>
00267
00268 Appends stuff to the named text block.
00269 If no text block name (C<$which>) is specified
00270 (in which case C<undef> must be used as a placeholder),
00271 the default C<'text'> block is used.
00272
00273 =cut
00274
00275 sub textAppend # $self, $which, @stuff
00276 {
00277 my $self = shift;
00278 my $which = shift || 'text';
00279
00280 push @{$self->{text}->{$which}}, @_
00281 }
00282
00283 ###########################################################################
00284
00285 =item C<textPop($self, $which)>
00286
00287 Pops the last thing appended to the named text block.
00288 If no text block name (C<$which>) is specified
00289 the default C<'text'> block is used.
00290
00291 The opposite of textAppend().
00292
00293 =cut
00294
00295 sub textPop # $self, $which
00296 {
00297 my $self = shift;
00298 my $which = shift || 'text';
00299
00300 pop @{$self->{text}->{$which}}
00301 }
00302
00303 ###########################################################################
00304
00305 =item C<textClear($self, $which, @stuff)>
00306
00307 Clears everything from the specified (C<$which>) text block,
00308 leaving it empty.
00309
00310 Text blocks might include C<brief>, C<comment>, C<text>.
00311 If no text block name (C<$which>) is specified
00312 (in which case C<undef> must be used as a placeholder),
00313 the default C<'text'> block is used.
00314
00315 =cut
00316
00317 sub textClear # $self, $which, @stuff
00318 {
00319 my $self = shift;
00320 my $which = shift || 'text';
00321
00322 delete $self->{text}->{$which}
00323 if exists $self->{text}->{$which}
00324 }
00325
00326 ###########################################################################
00327
00328 =item C<textString($self, $which)>
00329
00330 Returns text string with flattened (stringified) named text block.
00331
00332 Text blocks might include C<brief>, C<comment>, C<text>.
00333 If no text block name (C<$which>) is specified, the default
00334 C<'text'> block is used.
00335
00336 =cut
00337
00338 sub textString # $self, $which
00339 {
00340 my $self = shift;
00341 my $which = shift || 'text';
00342 my $this = $self->{text}->{$which};
00343
00344 isa($this, 'ARRAY') ? map { textThing() } @$this : textThing($this)
00345 }
00346
00347 ###########################################################################
00348
00349 =item C<textThing($self, $which)>
00350
00351 Returns the text string for an item of unknown provenance.
00352
00353 Internal use.
00354
00355 =cut
00356
00357 sub textThing # [ $this ]
00358 {
00359 my $this = shift || $_;
00360
00361 can($this, 'textString') ? $this->textString :
00362 can($this, 'image') ? $this->image : $this || ''
00363 }
00364
00365 ###########################################################################
00366 ###########################################################################
00367
00368 =item C<entities($self, $kind)>
00369
00370 Return all of the entities of a specific kind (e.g. classes, functions)
00371 from this item and all items it contains.
00372
00373 sub entities # $self, $kind
00374 {
00375 my ($self, $kind) = @_;
00376 my %result = ( );
00377
00378 if (isa($self->{$kind}, 'ARRAY')) {
00379 $result{$_->{name}} = $_ for @{$self->{$kind}};
00380 } elsif (isa($self->{$kind}, 'HASH')) {
00381 $result{$_} = $self->{$kind}->{$_} for keys %{$self->{$kind}};
00382 }
00383
00384 # for (@{$self->{brief}}, @{$self->{comment}}, @{$self->{notation}}) {
00385 # next unless isa $_, 'doxy::Item';
00386 #
00387 # $result{$_->{name}} = $_
00388 # for $_->entities($kind);
00389 # }
00390
00391 # Fixed perl RLaager's email, [2004/01/17]
00392 # should have different values by command line argument,
00393 # to support at least:
00394 # - alphabetical behavior [alpha]
00395 # - "as ordered" in source file [order]
00396 # so $self->{_sort_}->{$kind} may be one of the two bracketed
00397 # keywords (a string thereof). Will add setting mechanism,
00398 # but for now set to decent values in new().
00399 # %result = sort %result
00400 # if $self->{_sort_}->{$kind};
00401
00402 values %result
00403 }
00404
00405 =cut
00406
00407 ###########################################################################
00408 ###########################################################################
00409
00410 1
00411
00412 __END__
00413
00414 =back
00415
00416 =head1 SEE ALSO
00417
00418 DoxyFilt.pl
00419
00420 =head1 AUTHOR
00421
00422 Marc M. Adkins, L<mailto:Perl@Doorways.org>
00423
00424 =head1 COPYRIGHT AND LICENSE
00425
00426 Copyright 2004-2010 by Marc M. Adkins
00427
00428 This library is free software; you can redistribute it and/or modify
00429 it under the same terms as Perl itself.
00430
00431 =cut