<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">package kdoctexi;

# kdoctexi.pm -- C++ TexInfo output module for KDOC.
#		Copyright (C) 1998, Bernd Gehrmann
# $Id: kdoctexi.pm,v 1.6 2001/03/06 16:07:28 ssk Exp $

# The KDOC package is distributed under the GNU Public License.

use Ast;
use kdocAstUtil;
use kdocAstSearch;
use File::Path;
use File::Basename;
use Iter;
use kdocDocIter;

use strict;

use vars qw/ $lib $rootnode $outputdir @clist $depth /;

=head1 kdoctexi

	TexInfo output module.

=cut
    
sub writeDoc 
{
        ( $lib, $rootnode, $outputdir ) = @_;
  
        print "Generating texinfo documentation.\n" unless $main::quiet;

	mkpath( $outputdir ) unless -f $outputdir;

        makeClassList( $rootnode );
        writeMain();
        writeHierarchy();
        writeOverview();
        writeClasses();

}



sub makeClassList
{
	my ( $rootnode ) = @_;

	@clist = ();

	foreach my $node ( @ {$rootnode-&gt;{Kids}} ) {
		if ( !defined $node ) {
			print "makeClassList: undefined child in rootnode!\n";
			next;
		}

		push( @clist, $node ) unless exists $node-&gt;{ExtSource}
				|| !exists $node-&gt;{Compound};
	}

	@clist = sort { $a-&gt;{astNodeName} cmp $b-&gt;{astNodeName}  }
			@clist;
}



sub writeMain {

        open( TEXMAIN, "&gt;$outputdir/$lib.texi" ) 
	  || die "Couldn't write to $outputdir/$lib-main.texi\n";

        print TEXMAIN&lt;&lt;EOF;
\\input texinfo
\@c %**start of header
\@comment ----- automatically generated - do not edit! -----
\@afourpaper
\@setfilename $lib.info
\@settitle $lib documentation
\@headings on
\@setchapternewpage on
\@c %**end of header

\@include $lib-hier.tex
\@include $lib-overvw.tex
\@include $lib-inc.tex

\@page
\@comment \@printindex fn
\@shortcontents
\@bye
EOF

        close( TEXMAIN );
}



sub writeHierarchy 
{
	my @bullets = ( '@bullet', '*', '+', '-' );
	my $depth = 0;

        open( TEX, "&gt;$outputdir/$lib-hier.tex" ) 
	  || die "Couldn't write to $outputdir/$lib-hier.tex\n";
	
	print TEX "\@comment ----- automatically generated - do not edit! -----\n";
	print TEX "\@unnumbered $lib Class Hierarchy\n\n";

	Iter::Hierarchy( $rootnode,
		sub { # down
			my $bullet = $bullets[ $depth ];
			$bullet = "-" unless defined $bullet;
			++$depth;

			print TEX "\@itemize $bullet\n";
		},
		sub { # print
			my ($node) = @_;
			return if $node == $rootnode;

			my $src = defined $node-&gt;{ExtSource} ?
				" (from $node-&gt;{ExtSource})" : "";
			my $item = $depth &gt; 0 ? "\@item\n" : "";

			print TEX "$item\@code{",$node-&gt;{astNodeName},"$src}\n";
		},
		sub { # up
			print TEX "\@end itemize\n";
			--$depth;
		}
	);
		
	close TEX;
}


sub writeOverview 
{
	open( TEX, "&gt;$outputdir/$lib-overvw.tex" ) 
	  || die "Couldn't write to $outputdir/$lib-classes.tex\n";
	
	print TEX "\@comment ----- automatically generated - do not edit! -----\n";
	print TEX "\@unnumbered $lib Library Overview\n\n";

	if ( defined $rootnode-&gt;{DocNode} ) {
		writeDescription( $rootnode-&gt;{DocNode} );
	}


	print TEX "\@table \@asis\n";
	
	foreach my $node ( @clist ) {

                my $docnode = $node-&gt;{DocNode};

		my $short = "";
		if ( defined $docnode &amp;&amp; exists $docnode-&gt;{ClassShort} ) {
		        $short = formatText($docnode-&gt;{ClassShort});
		}

		my $className = $node-&gt;{astNodeName};

                # The following is really a dirty hack
                # Find something better!
		print TEX "\@item \@code{$className ";
	        print TEX "@ @ @ @ @ @ @ @ @ @ @ @ @ }", "\n";
		print TEX escape($short), "\n";
	}
						  
	print TEX "\@end table\n";
	close TEX;
}



sub writeClasses 
{
	open( TEXINC, "&gt;$outputdir/$lib-inc.tex" ) 
	  || die "Couldn't write to $outputdir/$lib-inc.tex\n";
	print TEXINC "\@comment ----- automatically generated - do not edit! -----\n";
	
	foreach my $node ( @clist ) {

		next if !defined $node-&gt;{Compound} 
		  || defined $node-&gt;{ExtSource};

		my $className = $node-&gt;{astNodeName};

		print TEXINC "\@include $className.tex\n";
		open( TEX, "&gt;$outputdir/$className.tex" ) 
		  || die "Couldn't write to $outputdir/$className.tex\n";
		print TEX "\@comment ----- automatically generated - do not edit! -----\n";

		writeClass( $node );
		close TEX;
	}
	
	close TEXINC;
}



sub writeClass 
{
	my ( $node ) = @_;

	my $docnode = $node-&gt;{DocNode};
	my $header = $node-&gt;{Source}-&gt;{astNodeName};
	my $className = $node-&gt;{astNodeName};
	
	my $classType = (exists $node-&gt;{Tmpl} )? "Template" : "Class";
	
	print TEX&lt;&lt;EOF;
\@unnumbered \@code\{$className\} $classType Reference \@i\{($header)\}
\@findex $className
EOF
	
	if ( exists $docnode-&gt;{Deprecated} ) {
		print TEX "\@noindent\n\@b{Deprecated Class}\n";
	}
	
	if ( exists $docnode-&gt;{Internal} ) {
		print TEX "\@noindent\n\@b{For internal use only}\n";
	}

	if ( exists $node-&gt;{Pure} ) {
		print TEX "\@noindent\n\@b{Contains pure virtuals}\n";
	}
	
	if ( $classType eq "template" ) {
		print TEX "\@table \@asis\n\@item Template form:\n",
		"\@code{template &lt;", escape( $node-&gt;{Tmpl} ),
		"&gt; ", $className, "}\n\@end table\n";
	}
	
	my $comma = "";

	Iter::Ancestors( $node, $rootnode, undef,
		sub { # start
			print TEX "\@table \@asis\n\@item Inherits:\n"
		},
		sub { # print
			my ( $n, $name, $type, $template ) = @_;
			my $source;

			if ( defined $n ) {
				$source = defined $n-&gt;{ExtSource} ?
				" ($n-&gt;{ExtSource})" : "";
				$name = $n-&gt;{astNodeName};
			}

			print TEX $comma, escape( $name ), $source, "\n";
		},
		sub { #end
			print TEX "\@end table\n";
		}
	);
	
	Iter::Descendants( $node, undef,
		sub { #start
			print TEX "\@table \@asis\n\@item Inherited by:\n";
			$comma = "";
		},
		sub { #print
			my ($in) = @_;
			my $source;
			$source = defined $in-&gt;{ExtSource} ?
				" ($in-&gt;{ExtSource})\n" :"\n";

			print TEX $comma, escape( $in-&gt;{astNodeName} ),
				$source;
		},
		sub { #end
			print TEX "\n\@end table\n";
		}
	);

        my $author   = $docnode-&gt;{Author};
        my $version  = $docnode-&gt;{Version};
        my $classSee = $docnode-&gt;{See};

	if( $author ne "" || $version ne "" || $classSee ne "" ) {
		my $escVersion = escape( $version );
		my $escAuthor = $author;
		$escAuthor =~ s/&lt;(.+\@\@.+)&gt;/\@email{$1}/mg;
		$escAuthor =~ s/\((.+\@\@.+)\)/\@email{$1}/mg;
		$escAuthor = formatText( $escAuthor );

		my $escSee = escape( $classSee );
		print TEX "\@table \@asis\n";
		print TEX "\@item Version:\n$escVersion\n" unless $escVersion eq "";
		print TEX "\@item Author:\n$escAuthor\n" unless $escAuthor eq "";		
		print TEX "\@item See Also:\n$escSee\n" unless $escSee eq "";		
		print TEX "\@end table\n";
	}
	
	writeDescription( $docnode );
	
	Iter::MembersByType( $node,
		sub {	#startgroup
			print TEX "\@unnumberedsec $_[0]\n";
		},
		sub {	# member
			my ( $node, $kid ) = @_;

			writeMember( $node, $kid );
		}
	);
}

sub writeMember 
{
	my ( $classnode, $member ) = @_;
	my $className = $classnode-&gt;{astNodeName};
	my $memberName = $member-&gt;{astNodeName};
        my $escName = escape( $memberName );
	my $type = $member-&gt;{NodeType};
        $_ = $type;
        SWITCH: {
		
		if( /^method/ ) {
			my $escRetType = escape( $member-&gt;{ReturnType} );
			my $escParams = escape( $member-&gt;{Params} );
			my $flags = $member-&gt;{Flags};
			my $docNode = $member-&gt;{DocNode};

			if ( $memberName eq $className ) {
				print TEX "\@deftypefn Constructor {} $escName {($escParams)}\n";
			}
			elsif ( $memberName eq "~$className" ) {
				print TEX "\@deftypefn Destructor {} $escName {($escParams)}\n";
			}
                        elsif ( $flags =~ /s/ ) {
				print TEX "\@deftypefn {Static Method} {$escRetType} $escName ",
				"{($escParams)}\n";
			}
			else {
				print TEX "\@deftypefn Method {$escRetType} $escName ",
				"{($escParams)}", $flags =~ /c/? " const\n" : "\n";
			}
			
			my $ref = kdocAstSearch::findOverride( $rootnode, 
					$classnode, $member-&gt;{astNodeName} );
			if ( defined $ref ) {
			        print TEX "Reimplemented from ",
								fullName($ref-&gt;{Parent}),"\n";
			}

			writeMemberInfo( $docNode ) if defined $docNode;
			
			kdocDocIter::ParamIter( $docNode,
				sub { # start
					print TEX "\@noindent\nParameters:\n",
						"\@multitable \@columnfractions .1 .15 .75\n";
				},
				sub { # end
					print TEX "\@end multitable\n";
				},
				sub { # print
					print TEX "\@item \@tab ",escape(shift)," \@tab ",
							escape(shift), "\n";
				}
			);
				
			my $returns = $docNode-&gt;{Returns};
			print TEX "\@noindent\nReturns: ", 
			escape($returns), "\n" unless $returns eq "";

			my $exceptions = $docNode-&gt;{Throws};
			if ( $exceptions ne "" ) {
				print TEX "\@noindent\n\@table ",
				"\@asis\n\@item Throws:\n",
				escape($exceptions), "\n\@end table\n";
			}

			print TEX "\@end deftypefn\n\n";
			last SWITCH;
		} # /^method/
		
		if ( /^var/ ) {
			my $type = $member-&gt;{Type};
			print TEX "\@deftypevar ", escape($type), " $escName\n";
			writeMemberInfo( $member-&gt;{DocNode} );
			print TEX "\@end deftypevar\n";
			last SWITCH;
		} # /^var/
		
		if( /^typedef/ ) {
			my $escType = escape( $member-&gt;{Type} );
			print TEX "\@deftp {typedef} {$escType} $escName\n";
			writeMemberInfo( $member-&gt;{DocNode});
			print TEX "\@end deftp\n";
			last SWITCH;
		} # /^typedef/
		
		if ( /^enum/ ) {
			# I'm not really convinced that it makes sense to list all constants.
			# Normally, I would expect that all constants are explained in the
			# doc comment, embedded in a &lt;ul&gt;..&lt;/ul&gt; list.
			my $escConstants = escape( $member-&gt;{Params} );
			$escConstants =~ s/\n+/\n/g;
                        my $enumName = ($escName =~ /^\s*$/)? 
				"(Anonymous)" : $escName;
			print TEX "\@deftp Enumeration \@code{enum} $enumName\n";
			print TEX "\@example\nenum $enumName \@{\n",
			"$escConstants\@};\n\@end example\n";
			writeMemberInfo( $member-&gt;{DocNode} );
			print TEX "\@end deftp\n";
			last SWITCH;
		} # /^enum/
		
	} # SWITCH
	
}



sub writeDescription 
{
	kdocDocIter::TextIter( shift,
		undef,#start
		sub { #end
			print TEX "\n";
		},
		sub { #text
			print TEX formatText( $_[1] );
		},
		sub { #ref
			print TEX formatText( $_[1] );
		},
		sub { #sect
		},
		sub { #pre
			print TEX "\@example\n",escape($_[1]),"\n\@end example\n";
		},
		undef, #image
		sub { #para
			print TEX "\n\n";
		},
		sub { #list start
			print TEX "\@itemize \@bullet\n";
		},
		sub { #list end
			print TEX "\@end itemize\n";
		},
		sub { #item
			print TEX "\@item ", formatText($_[1]), "\n";
		}
	);
}



sub writeMemberInfo 
{

        my ( $docnode ) = @_;

	writeDescription( $docnode );
	
#	if( $MethDeprecated ) {
#		print TEX "\@noindent\n\@b{Deprecated Member}\n";
#	}
#	
#	if( $MethInternal ) {
#		print TEX "\@noindent\n\@b{For internal use only}\n";
#	}
	
}


# This is for conversion of general, non-preformatted text

sub formatText 
{
	my ( $text ) = @_;
	
	$text = escape($text);
	# After escape, @ is @@
	$text =~ s/\@\@ref\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
        $text =~ s/\@\@ref\s+(#|::)?([\w\d_~]+)/$2/g;
	$text =~ s/\@\@see\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
        $text =~ s/\@\@see\s+(#|::)?([\w\d_~]+)/$2/g;
	$text =~ s/&lt;em&gt;/\@emph\{/ig;
	$text =~ s/&lt;\/em&gt;/\}/ig;
	$text =~ s/&lt;strong&gt;/\@strong\{/ig;
        $text =~ s/&lt;\/strong&gt;/\}/ig;
        $text =~ s/&lt;dfn&gt;/\@dfn\{/ig;
        $text =~ s/&lt;\/dfn&gt;/\}/ig;
        $text =~ s/&lt;code&gt;/\@code\{/ig;
        $text =~ s/&lt;\/code&gt;/\}/ig;
        $text =~ s/&lt;samp&gt;/\@samp\{/ig;
        $text =~ s/&lt;\/samp&gt;/\}/ig;
        $text =~ s/&lt;kbd&gt;/\@kbd\{/ig;
        $text =~ s/&lt;\/kbd&gt;/\}/ig;
        $text =~ s/&lt;var&gt;/\@var\{/ig;
        $text =~ s/&lt;\/var&gt;/\}/ig;
        $text =~ s/&lt;cite&gt;/\@cite\{/ig;
        $text =~ s/&lt;\/cite&gt;/\}/ig;
        $text =~ s/&lt;i&gt;/\@i\{/ig;
        $text =~ s/&lt;\/i&gt;/\}/ig;
        $text =~ s/&lt;b&gt;/\@b\{/ig;
        $text =~ s/&lt;\/b&gt;/\}/ig;
        $text =~ s/&lt;tt&gt;/\@t\{/ig;
        $text =~ s/&lt;\/tt&gt;/\}/ig;

        $text =~ s/&lt;br&gt;/\@*/ig;
        $text =~ s/&lt;p&gt;/\n/ig;
        $text =~ s/&lt;\/p&gt;//ig;
			 
        $text =~ s/&amp;lt;/&lt;/g;
        $text =~ s/&amp;gt;/&gt;/g;
        $text =~ s/&amp;amp;/&amp;/g;
        $text =~ s/&amp;nbsp;/\@ /g;
        $text =~ s/&amp;copy;/\@copyright{}/g;

# Support for other languages?
        $text =~ s/&amp;auml;/\@"a/g;
        $text =~ s/&amp;ouml;/\@"o/g;
        $text =~ s/&amp;uuml;/\@"u/g;
        $text =~ s/&amp;Auml;/\@"A/g;
        $text =~ s/&amp;Ouml;/\@"O/g;
        $text =~ s/&amp;Uuml;/\@"U/g;
        $text =~ s/&amp;szlig;/\@ss/g;

        $text =~ s/^\s*&lt;blockquote&gt;\s*$/\@quotation/mig;
        $text =~ s/^\s*&lt;\/blockquote&gt;\s*$/\@end quotation/mig;
        $text =~ s/^\s*&lt;ul&gt;\s*$/\@itemize \@bullet/mig;
        $text =~ s/^\s*&lt;\/ul&gt;\s*$/\@end itemize/mig;
        $text =~ s/^\s*&lt;ol&gt;\s*$/\@enumerate/mig;
        $text =~ s/^\s*&lt;\/ol&gt;\s*$/\@end enumerate/mig;
        $text =~ s/^\s*&lt;dl&gt;\s*$/\@table \@asis/mig;
        $text =~ s/^\s*&lt;\/dl&gt;\s*$/\@end table/mig;
        $text =~ s/^\s*&lt;li&gt;/\@item /mig;
        $text =~ s/^\s*&lt;\/li&gt;//mig;
        $text =~ s/^\s*&lt;dt&gt;/\@item /mig;
        $text =~ s/^\s*&lt;\/dt&gt;//mig;
        $text =~ s/^\s*&lt;dd&gt;//mig;
        $text =~ s/^\s*&lt;\/dd&gt;//mig;

        return $text;
}

sub fullName
{
	return join( "::", kdocAstUtil::heritage( shift ) );
}

# This is for preformatted or similar text
sub escape 
{
	my( $text ) = @_;
	
	$text =~ s/([\@\{\}])/\@$1/g;

# i18n support
#  $text =~ s/ä/\@"a/g;
#  $text =~ s/ö/\@"o/g;
#  $text =~ s/ü/\@"u/g;
#  $text =~ s/Ä/\@"A/g;
#  $text =~ s/Ö/\@"O/g;
#  $text =~ s/Ü/\@"U/g;
#  $text =+ s/ß/\@ss{}/g;

	return $text;
}

#

sub deref
{
	my ( $str ) = @_;
	my $out = "";
	my $text;

	$str =~ s/\@\@ref\s+([\w\d_~]+)(#|::)([\w\d_~]+)/$1::$3/g;
        $str =~ s/\@\@ref\s+(#|::)?([\w\d_~]+)/$2/g;
        $out = $str;

#	foreach $text ( split (/(\@ref\s+[\w:#]+)/, $str ) ) {
#		if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
#			$out .= $1;
#		}
#		else {
#			$out .= $text;
#		}
#	}
	
	return $out;
}

1;
</pre></body></html>