[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kdoc
Subject:    LaTeX resurrected
From:       Marcin Kasperski <Marcin.Kasperski () softax ! com ! pl>
Date:       1999-04-26 12:20:34
[Download RAW message or body]

As I needed it, I resurrected LaTeX output (I use it to generate pretty
PDF documents with pdflatex). Here is what I did:

1) I added to kdoc main file:

@@ -174,6 +174,11 @@
 				kdoctexi::writeDoc( $libname,
 				$node, $outputdir, \%options );
 			}
+			if ( exists $options{latex} ) {
+				require kdocCxxLaTeX;
+				kdocCxxLaTeX::writeDoc( $libname,
+                                                    $node, $outputdir,
\%options );
+			}
 			if ( exists $options{html} ) {
 				require kdocCxxHTML;
 				kdocCxxHTML::writeDoc( $libname, $node, 

2) I copied kdocCxxHTML.pm to kdocCxxLaTeX.pm and started hacking it.
The resulting file is attached to this letter. It creates many small
latex files and the file main.tex which is to be LaTeX'ed (and which
includes all those small files) - that allows me to easily merge for
instance reference and manual into one book.

Two words of warning:
- I create polish documents, if anyone need another language it should
be just changed (i.e. you should remove/change \usepackage{inputenc} and
\usepackage{polski} into sth. correct for you)
- I use great package called listings to generate header listings. It is
available on CTAN.
- It works now as-is but not everything is finished yet (there are some
sub's with html rubbish inside my file - they are not called)

Regards.

-- Marcin Kasperski     Marcin.Kasperski<at>softax.com.pl
--                      marckasp<at>friko6.onet.pl
-- Moje poglądy są moimi poglądami, nikogo poza mną nie reprezentują.
-- (My opinions are just my opinions.)
["kdocCxxLaTeX.pm" (text/plain)]

package kdocCxxLaTeX;

use File::Path;
use File::Basename;

use Carp;
use Ast;
use kdocAstUtil;

=head1 kdocCxxLaTex

Capabilities required from Ast bit: 

1. Create an inheritance tree

2. Referencing ability: convert a fully qualified class or member name
	to a node reference.

=cut

BEGIN
{
	@clist = ();
	@docQueue = ();

        eval { 
          use Sys::Hostname;
          $host = hostname();
          chomp $host;
        };
        eval { 
          $who = `whoami`;	
	  if($who =~ /DCL-W-IVVERB/) {
	      $who = `show process`;
	      ($who) = ($who =~ /User: ([^\s]+)\s/);
	  }
          chomp $who; 
        };
        $now = localtime;	
        chomp $now; 
        $gentext = "$who\@$host, $now.";
}

sub writeDoc
{
	( $lib, $rootnode, $outputdir, $opt ) = @_;

	$debug = $main::debug;

	print "Generating LaTeX documentation. \n" unless $main::quiet;

	mkpath( $outputdir ) unless -f $outputdir;

# ??? Przywrócić w LaTeXowej wersji
#	makeReferences( $rootnode );
	makeClassList( $rootnode );

        startMainDocument();

# ??? Wykomentowane rzeczy jeszcze nie przerobione

	writeGlobalDoc( $rootnode );
	writeAnnotatedList( $rootnode );
	writeHier( $rootnode );
#	writeHeaderList();

	foreach $node ( @{$rootnode->{Kids}} ) {
		next if !defined $node->{Compound} 
			|| defined $node->{ExtSource}
			|| $node->{NodeType} eq "Forward";

		push @docQueue, $node;
	}

        # Próbujemy posortować tą kolejkę
        @docQueue = sort { $b->{astNodeName} cmp $a->{astNodeName} } @docQueue;

	while( $#docQueue >= 0 ) {
		$node = pop @docQueue;
		writeClassDoc( $node );
	}

	print "Generating LaTeXized headers.\n" unless $main::quiet;
	foreach $header ( @main::ARGV ) {
		markupCxxHeader( $header, $rootnode );
	}

        finishMainDocument();
}

=head2 writeAnnotatedList

	Parameters: rootnode

	Writes out a list of classes with short descriptions to
	index-long.tex.

=cut

sub writeAnnotatedList
{
	my ( $root ) = @_;
	my $short;

	open(CLIST, ">$outputdir/index-long.tex") 
	|| die "Couldn't create $outputdir/index-long.tex\n";

        print MAIN "\\input{index-long.tex}\n\n";

	print CLIST sectionHeader( "Lista klas " . $lib );
        print CLIST <<EOF;
\\begin{longtable}{lp{8cm}}        
EOF
	foreach $node ( @clist ) {
		print  "undef in clist\n" if !defined $node;

		$docnode = $node->{DocNode};
		$short = "";

		if( defined $docnode && exists $docnode->{ClassShort} ) {
			$short = deref($docnode->{ClassShort}, $rootnode );
			if( !defined $short ) {
				print $root->{astNodeName}, "has undef short\n";
				next;
			}
				
		}

		print CLIST refName($node), ' & ', $short, "\\\\\n";                
	}

	print CLIST "\\end{longtable}\n";
	close CLIST;
}

=head2 writeClassList

	Parameters: rootnode

	Writes out a concise list of classes to index.tex

=cut

=head3

	Parameters: list, start index, end index

	Helper for writeClassList.  Prints a table containing a
	hyperlinked list of all nodes in the list from start index to
	end index. A table header is also printed.

=cut

sub writeListPart
{
	my( $list, $start, $stop ) = @_;

	print CLIST "<TABLE BORDER=\"0\">";

	print CLIST "<TR><TH>", 
		esc( $list->[ $start ]->{astNodeName} ),
		" - ", esc( $list->[ $stop ]->{astNodeName} ), 
		"</TH></TR>";

	for $ctr ( $start..$stop ) {
		print CLIST "<TR><TD>", refName( $list->[ $ctr ] ),
			"</TD></TR>\n";
	}

	print CLIST "</TABLE>";
}


=head2 writeAllMembers

	Parameters: node

	Writes a list of all methods to "full-list-<class file>"

=cut

sub writeAllMembers
{
	my( $node ) = @_;
	my $file = "$outputdir/full-list-".$node->{Ref};
	my %allmem = ();

	kdocAstUtil::allMembers( \%allmem, $node );

	open( ALLMEM, ">$file" ) || die "Couldn't create $file\n";

        my $thisClassName = $node->{astNodeName};
	print ALLMEM sectionHeader( "Wszystkie metody " . esc($thisClassName) ),
		"<UL>";

	my $mem;
	foreach $mem ( sort keys %allmem ) {
                my $parentName = $allmem{$mem}->{Parent}->{astNodeName};
		print ALLMEM "<LI>";
                print ALLMEM refName( $allmem{ $mem } );
                if($parentName ne $thisClassName) {
                  print ALLMEM " <small>[$parentName]</small>"
                }
                print ALLMEM "</LI>\n";
	}

	print ALLMEM "</UL>$docBotty";

	close ALLMEM;
}

=head2 writeHier

	Parameters: rootnode

	Writes out the class hierarchy index to hier.html.

=cut

sub writeHier
{
	my ( $root ) = @_;

	open( HIER, ">$outputdir/hier.tex") 
		|| die "Couldn't create $outputdir/hier.tex\n";

        print MAIN "\\input{hier.tex}\n\n";

	print HIER sectionHeader( "Hierarchia klas " . $lib );

	printNodeHier( $root, 0 );

	close HIER;
}

=head3 printNodeHier

	Parameters: node

	Lists all classes that inherit from this node in an unordered list.

=cut

sub printNodeHier 
{
	my( $node, $level ) = @_;
	my $kid;
	my $src = "";

	# non-derived external classes are not printed.
	if ( defined $node->{ExtSource} ) {
		return if !defined $node->{InBy} 
			|| !kdocAstUtil::hasLocalInheritor( $node );

		$src = "{\\small ".$node->{ExtSource}.")}";
	}

#	print HIER "\\item ", 
        print HIER "\\verb!", '   ' x $level, "!",
                   refName( $node )," $src\\\\\n" 
	    unless $node == $rootnode;

	return if !defined $node->{InBy};

#	print HIER "\\begin{itemize}\n";

	foreach $kid ( sort { $a->{astNodeName} cmp $b->{astNodeName} } 
			@{ $node->{InBy} } ) {
		printNodeHier( $kid, $level + 1 );
	}
#	print HIER "\\end{itemize}\n";
}

=head2 writeHeaderList

	Generates the header-list.html file, which contains links
	to each processed header. The ARGV list is used.

=cut

sub writeHeaderList
{
	open(HDRIDX, ">$outputdir/header-list.html") 
	|| die "Couldn't create $outputdir/header-list.html\n";

	print HDRIDX sectionHeader( "Lista plików " . $lib ), "<UL>\n";

	foreach $header ( sort @main::ARGV ) {
		$_ = $header;
		$header = basename ( $_ ) if $main::striphpath;
# convert dashes to double dash, convert path to dash
		s/-/--g/g;
		s/\/|\./-/g;

		print HDRIDX  "\t<LI>",hyper($_.".html",$header),"</LI>\n";
	}
	
	print HDRIDX "</UL>\n",$docBotty;

}

=head2 sectionHeader

	Parameters: libname, heading

	Returns a string containing an HTML section heading.

=cut

sub sectionHeader
{
	my( $heading, $desc ) = @_;

	$desc = "" if !defined $desc;

	my $libtext = "";
	if( $lib ne "" ) {
		$libtext = "<TR><TD><small>Dokumentacja $lib</small>".
			"</TD></TR>";
	}

	return <<EOF;
\\section{$heading}

EOF
	
}

=head2 writeClassDoc

	Write documentation for one compound node.

=cut

sub writeClassDoc
{
	my( $node ) = @_;
	if( exists $node->{ExtSource} ) {
		warn "Trying to write doc for ".$node->{AstNodeName}.
			" from ".$node->{ExtSource}."\n";
		return;
	}

	my $file = "$outputdir/".$node->{astNodeName}.".tex";
	my $docnode = $node->{DocNode};
	my $hasdoc = exists $node->{DocNode} ? 1 : 0;
	my @list = ();
	my $version = undef;
	my $author = undef;

	open( CLASS, ">$file" ) || die "Couldn't create $file\n";

        print MAIN "\\input{".$node->{astNodeName}.".tex}\n\n";

	# Header
	 
	my $source = kdocAstUtil::nodeSource( $node );
	my $short = "";

	if( $hasdoc ) {
		if ( exists $docnode->{ClassShort} ) {
#			$short .= deref($docnode->{ClassShort}, $rootnode );
			$short .= $docnode->{ClassShort};
		}

		if ( exists $docnode->{Deprecated} ) {
			$short .= "\n\n\\textbf{Przestarzałe: używać ostrożnie.}";
		}

		if ( exists $docnode->{Internal} ) {
			$short .= "\n\n\\textbf{Tylko do wewnętrznego użytku.}";
		}
		$version = esc($docnode->{Version}) 
			if exists $docnode->{Version};
		$author = esc($docnode->{Author}) 
			if exists $docnode->{Author};
	}

	# pure virtual check
	if ( exists $node->{Pure} ) {
		$short .= 
			"\n\n\\textbf{Klasa abstrakcyjna}\n\n";
	}
	
	# full name, if not in global scope
	if ( $node->{Parent} != $rootnode ) {
		$short .= "\n\n\\texttt{".refNameEvery( $node )
				."}";
	}

	# include
        # MK --> hack (link z #include)
	$short .= "\n\n\\verb!#include <".$source.">!\n\n";

	# template form
	if ( exists $node->{Tmpl} ) {
		$short .= "\n\nKlasa parametryzowana (template): \\verb!<"
			.textRef($node->{Tmpl}, $rootnode)."> ".
			esc($node->{astNodeName}, 
			$rootnode )."!\n\n";
	}

	# inheritance
	if ( $node != $rootnode && exists $node->{InList} ) {
		my $comma = "Dziedziczy z: ";

		foreach $in ( @{ $node->{InList} } ) {
			next if $in == $rootnode;

			$short .= $comma.refName( $in );
			if ( exists $in->{ExtSource} ) {
				$short .= " {\\small(".$in->{ExtSource}
					.")}";
			}
			
			$comma = ", ";
		}

		$short .= "\n\n";
	}

	if ( $node != $rootnode && exists $node->{InBy} ) {
		my $comma .= "Klasy dziedziczące: ";

		@list = ();
		kdocAstUtil::inheritedBy( \@list, $node );

		foreach $in ( @list ) {
			$short .= $comma.refName( $in );
			if ( exists $in->{ExtSource} ) {
				$short .= " {\\small(".
				$in->{ExtSource}.")}";
			}
	
			$comma = ", ";
		}
		$short .= "\n\n";
	}

	# print it

	print CLASS sectionHeader( 
		$node->{NodeType}." ".esc($node->{astNodeName}), 
		$short );

	if( $#{$node->{Kids}} < 0 ) {
		print CLASS <<EOF;
\\begin{quote}
Brak składowych
\\end{quote}
EOF
	}
	else {
		listMethods( $node, "Składowe publiczne", "public" );
		listMethods( $node, "Public Slots", "public_slots" );
		listMethods( $node, "Składowe chronione", "protected" );
		listMethods( $node, "Protected Slots", "protected_slots" );
		listMethods( $node, "Signals", "signals" );

		if ( $main::doPrivate ) {
			listMethods( $node, "Składowe prywatne", "private" );
			listMethods( $node, "Private Slots", "private_slots" );
		}
	}

	# long description
	if ( $hasdoc ) {
		print CLASS "\n\\subsection*{Opis klasy}\n\n";
		printDoc( $docnode, *CLASS, $rootnode, 1 );
	}

	# member doc
	my $kid;
	my ($numref, $ref);

	foreach $kid ( @{$node->{Kids}} ) {
			next if defined $kid->{ExtSource} 
			|| $node->{NodeType} eq "Forward"
			|| (!$main::doPrivate && 
				$kid->{Access} =~ /private/);

		if ( exists $kid->{Compound} ) {
			push @docQueue, $kid;
		}

		next if !defined $kid->{DocNode};

# ??? Przywrócić kiedyś
#		if( !exists $kid->{NumRef} ) {
#			warn $kid->{astNodeName}, " type ",
#			$kid->{NodeType}, " doesn't have a numref\n";
#		}

# ??? Przywrócić kiedyś ???
#		( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
#		( $ref = $kid->{Ref} ) =~ s/^.*?#//g;

		printMemberName( $kid, $ref, $numref );
		printDoc( $kid->{DocNode}, *CLASS, $rootnode );

		if ( $kid->{NodeType} eq "method" ) {
			$ref = kdocAstUtil::findOverride( $rootnode, $node, 
				$kid->{astNodeName} );
			if ( defined $ref ) {
				print CLASS "\n\nPrzykrywa metodę z klasy ",
					refName( $ref ), "\n\n";
			}
		}
	}

	# done

#	if ( defined $version || defined $author ) {
#		print CLASS "\\begin{itemize}\n",
#			defined $version ? 
#                          "\\item Wersja: $version;\n" : "",
#			defined $author ? 
#                          "\\item Autor: $author;\n" : "",
#                          "\\item Generowane: $gentext;\n",
#                          "\\end{itemize}\n";
#	}
#	else {
#		print CLASS "Generowane: $gentext\n";
#	}

	close CLASS;

	# full member list

#      ??? Kiedyś jednak zrobić
#	writeAllMembers( $node );
}

sub writeGlobalDoc
{
	my( $node ) = @_;
	my $file = "$outputdir/all-globals.tex";
	my $docnode = $node->{DocNode};
	my $hasdoc = exists $node->{DocNode} ? 1 : 0;
	my @list = ();
	my $cumu = Ast::New( "nodelist" );
	my $kid;

	# make a list of nodes by file
	foreach $kid ( @{$node->{Kids}} ) {
		next if exists $kid->{ExtSource} 
			|| exists $kid->{Compound}
			|| (!$main::doPrivate && 
				$kid->{Access} =~ /private/);

		$cumu->AddPropList( kdocAstUtil::nodeSource( $kid ), $kid )
			unless !exists $kid->{Source};
	}

	open( CLASS, ">$file" ) || die "Couldn't create $file\n";

        print MAIN "\\input{all-globals.tex}\n\n";

	print CLASS sectionHeader( "Zmienne, typy i funkcje globalne " . $lib);
	@list = sort keys %$cumu;

	foreach $file ( @list ) {
		next if $file eq "astNodeName";

		listMethods( $node, esc($file), "", $cumu->{$file} );
	}

	# member doc
	my ($numref, $ref);

	foreach $file ( @list ) {
		next if $file eq "astNodeName";
		
		foreach $kid ( @{$cumu->{$file}} ) {
			next if exists $kid->{ExtSource} 
			|| exists $kid->{Compound}
			|| !exists $kid->{DocNode}
			|| (!$main::doPrivate && 
					$kid->{Access} =~ /private/);

# ??? Przywrócić kiedyś
#			if( !exists $kid->{NumRef} ) {
#				warn $kid->{astNodeName}, " type ",
#				$kid->{NodeType}, " doesn't have a numref\n";
#			}

# ??? Przywrócić kiedyś
#			( $numref = $kid->{NumRef} ) =~ s/^.*?#//g;
#				( $ref = $kid->{Ref} ) =~ s/^.*?#//g;

                        printMemberName( $kid, $ref, $numref );
                        
			print CLASS "\n\n{\\small\\verb!#include <",
				kdocAstUtil::nodeSource( $kid ), 
				">!}\n\n";

			printDoc( $kid->{DocNode}, *CLASS, $rootnode );
		}
	}

#	print CLASS $docBotty;
	close CLASS;
}

sub listMethods
{
	my( $class, $desc, $vis, $nodes ) = @_;
	my $name;
	my $type;
	my $flags;
	my @n=();
	
	if ( !defined $nodes ) { 
		kdocAstUtil::findNodes( \@n, $class->{Kids}, 
			"Access", $vis );
		$nodes = \@n;
	}

	return if ( $#{$nodes} < 0 );

print CLASS<<EOF;
\\subsection*{$desc}

\\begin{itemize}
EOF
	foreach $m ( @$nodes ) {
		next if exists $m->{ExtSource};
		if( exists $m->{Compound} ) {
			# compound docs not printed for rootnode
			next if $class eq $rootnode; 

			$name = refName( $m );
		}
		elsif( exists $m->{DocNode} ) {
			# compound nodes have their own section
			$name = refName( $m,  'NumRef' );
		} else {
			$name = esc( $m->{astNodeName} );
		}

		$type = $m->{NodeType};

		print CLASS "\\item ";

		if( $type eq "var" ) {
			print CLASS esc( $m->{Type}), 
				" \\textbf{", $name,"}\n";
		}
		elsif( $type eq "method" ) {
			$flags = $m->{Flags};

			if ( !defined $flags ) {
				warn "Method ".$m->{astNodeName}.
					" has no flags\n";
			}

			$name = "\\emph{$name}" if $flags =~ /p/;
			my $extra = "";
			$extra .= "virtual " if $flags =~ "v";
			$extra .= "static " if $flags =~ "s";

			print CLASS $extra, esc($m->{ReturnType}),
				" \\textbf{", $name, "} (", 
				esc($m->{Params}), ") ", 
				$flags =~ /c/ ? " const\n": "\n";
		}
		elsif( $type eq "enum" ) {
			print CLASS "enum \\textbf{", $name, "} {",
				esc($m->{Params}),"}\n";
		}
		elsif( $type eq "typedef" ) {
			print CLASS "typedef ", 
				esc($m->{Type}), " \\textbf{",
				$name,"}";
		}
		else { 
			# unknown type
			print CLASS esc($type), " \\textbf{",
				$name,"}\n";
		}

		print CLASS "\n";
	}

print CLASS<<EOF;
\\end{itemize}
EOF

}

=head2 printIndexEntry

	Parameters: member node

	Prints an index entry for a single node.

	TODO: stub

=cut

sub printIndexEntry
{
	my ( @node ) = @_;
}

=head2 printMemberName

	Parameters: member node, names...

	Prints the name of one member, customized to type. If names are
	specified, a name anchor is written for each one.

=cut

sub printMemberName
{
	my $m = shift;

	my $name = esc( $m->{astNodeName} );
	my $type = $m->{NodeType};
	my $ref;
	my $flags = undef;

	foreach $ref ( @_ ) {
# ??? Pomyśleć o tym
#		print CLASS "\\label{", $ref, "}";
	}

#	print CLASS "\n\n\\textbf{";
	print CLASS "\n\n\\subsubsection*{";

	if( $type eq "var" ) {
		print CLASS textRef($m->{Type}, $rootnode ), 
		" \\texttt{", $name,"} ";
	}
	elsif( $type eq "method" ) {
		$flags = $m->{Flags};
		$name = "\\emph{$name}" if $flags =~ /p/;

		print CLASS textRef($m->{ReturnType}, $rootnode ),
		" \\texttt{", $name, "} (", 
		textRef($m->{Params}, $rootnode ), ") ";
	}
	elsif( $type eq "enum" ) {
		print CLASS "enum \\texttt{", $name, "} {",
		esc($m->{Params}),"} ";
	}
	elsif( $type eq "typedef" ) {
		print CLASS "typedef ", 
		textRef($m->{Type}, $rootnode ), " \\texttt{",
		$name,"} ";
	}
	else {
		print CLASS $name, " {\\small (", 
			esc($type), ")} ";
	}

# extra attributes
	my @extra = ();

	if( !exists $m->{Access} ) {
		print "Member without access:\n";
		kdocAstUtil::dumpAst( $m );
	}

	($ref = $m->{Access}) =~ s/_slots//g;

	push @extra, $ref
		unless $ref =~ /public/
		|| $ref =~ /signal/;

	if ( defined $flags ) {
		my $f;
		my $n;
		foreach $f ( split( "", $flags ) ) {
			$n = $main::flagnames{ $f };
			warn "flag $f has no long name.\n" if !defined $n;
			push @extra, $n;
		}
	}

	if ( $#extra >= 0 ) {
		print CLASS " {\\small [", join( " ", @extra ), "]}";
	}

	print CLASS "}"; # Po subsubsection
	print CLASS "\n\n";
	
# finis
}



=head2 makeClassList

	Parameters: node

	fills global @clist with a list of all direct, non-external
	compound children of node.

=cut

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

	@clist = ();

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

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

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

# MK --> skopiowane z 1.0
sub markupCxxHeader
{
	my( $filename, $rootnode ) = @_;
	$className = "";
	my( $reference );
	my( @inheritance );
	my( $word );

	open( HFILE, $filename ) || die "Couldn't open $filename to read.\n";

	$_ = $filename;
	# convert dashes to double dash, convert path to dash
	s/-/--g/g;
	s/\/|\./-/g;
	$outputName = $_;
	$outputFilename = $outputdir."/".$outputName;

	open( HTMLFILE, ">$outputFilename.tex" ) 
		|| die "Couldn't open $outputFilename to write.\n";

        print MAIN "\\input{$outputName.tex}\n\n";

        print HTMLFILE sectionHeader( esc("$filename") );

        print HTMLFILE <<EOF;
\\selectlisting{cpp}
\\begin{listing}
EOF
	while( <HFILE> )
	{
          print HTMLFILE;

# ??? Coś zrobić
#		if( /^\s*(template.*\s+)?(class|struct)/ ) {
#                    if($rootnode) {
#			$_ = textRef($_, $rootnode);
#                    } else {
#                        print STDERR "$0: can not make hyperlinks in file $filename\n";
#                    }
#		}

	}

        print HTMLFILE <<EOF;
\\end{listing}
EOF
}

sub startMainDocument {

  open(MAIN, ">$outputdir/main.tex")
    || die "Couldn't create $outputdir/main.tex\n";
    
  print MAIN <<EOF;
\\documentclass[a4paper,10pt]{article}

% Geometria strony (twoside ?)
\\usepackage[a4paper,hmargin={2cm,2cm},vmargin={2cm,2cm}]{geometry}

\\usepackage[latin2]{inputenc}
\\usepackage{polski}

\\usepackage{longtable}

% Specyficzne listingi
\\usepackage{listings}
\\keywordstyle{\\bfseries\\sffamily}
%\\commentstyle{\\slshape}
\\commentstyle{\\itshape}
%\\stringstyle{\\ttfamily}
\\blankstringtrue
\\prelisting{\\small\\sffamily}

% Przynajmniej nie będzie krzyczał
% \\catcode`\\_=12

% Odstępy między akapitami itp
\\setlength{\\parindent}{0cm}
\\addtolength{\\parskip}{1ex}

\\title{Dokumentacja referencyjna $lib}

\\begin{document}

\\maketitle
\\tableofcontents

\\begin{abstract}
Dokumentacja referencyjna $lib. 

Generowana: $gentext.
\\end{abstract}

EOF
}

sub finishMainDocument {
  print MAIN <<EOF;

\\end{document}
EOF
}

sub esc
{
	my $str = $_[ 0 ];

	return "" if !defined $str || $str eq "";

        # Trzeba zrobić sztuczkę by nie zamieniać własnych klamerek
        # lub backslashy
	$str =~ s/{/\\lbrace/g;
	$str =~ s/}/\\rbrace/g;
        $str =~ s/\\/\\ensuremath{\\backslash}/g;
#	$str =~ s/{/\\{/g;
#	$str =~ s/}/\\}/g;

        $str =~ s/</\\ensuremath{<}/g;
        $str =~ s/>/\\ensuremath{>}/g;
	$str =~ s/#/\\#/g;
	$str =~ s/%/\\%/g;
	$str =~ s/&/\\&/g;
	$str =~ s/\$/\\\$/g;
	$str =~ s/_/\\_/g;
        $str =~ s/~/\\ensuremath{\\sim}/g;
#        $str =~ s/\^/{\\ensuremath{^}}/g;

	return $str;
}

sub refName
{
	my ( $node ) = @_;
	confess "refName called with undef" if !defined $node->{astNodeName};

	my $ref = defined $_[1] ? $_[1] : 'Ref';

	$ref = $node->{ $ref };

	my $out;

#	if ( !defined $ref ) {
        $out =  esc($node->{astNodeName});
#	} else {
#		$out = '<A HREF="'.encodeURL($ref).'">'.
#			esc($node->{astNodeName}).'</A>';
#	}

	$out = "\\emph{".$out."}" if exists $node->{Pure};

#        print "DIAG: refName zwraca $out\n";
	return $out;

}

sub deref
{
	my ( $str, $rootnode ) = @_;
	confess "rootnode is null" if !defined $rootnode;

	my $out = "";
	my $text;

	foreach $text ( split (/(\@ref\s+[\w:#]+)/, $str ) ) {
		if ( $text =~ /\@ref\s+([\w:#]+)/ ) {
                        my $x = wordRef( $1, $rootnode );
#                        print "DIAG: w derefie $1 -> $x\n";
			$out .= $x;
		}
		else {
			$out .= esc($text);
		}
	}
	
#        print "DIAG: deref dla\n$str\nzwraca\n$out\n" if $str ne $out;
	return $out;
}

=head2 printDoc

	Parameters: docnode, *filehandle, rootnode, compound

	Print a doc node. If compound is specified and non-zero, various
	compound node properties are not printed.

=cut

sub printDoc
{
        local ($docNode, *CLASS, $rootnode, $comp ) = @_;
        my $node;
        my $type;
	my $text;
	my $lasttype = "none";

	$comp = defined $comp? $comp : 0;
	
	$text = $docNode->{Text};

        if ( defined $text ) {
                print CLASS "\n\n";

                foreach $node ( @$text ) {
                        $type = $node->{NodeType};
			$name = $node->{astNodeName};
                        warn "Node '", $name, "' has no type"
				if !defined $type;

			if( $lasttype eq "ListItem" && $type ne $lasttype ) {
				print CLASS "\\end{itemize}\n";
			}

                        if( $type eq "DocText" ) {
                                print CLASS "", deref( $name, $rootnode );
                        }
                        elsif ( $type eq "Pre" ) {
# ??? verbatim'ów nie escapeuję. Ale może w ogóle użyć tu listings
                                print CLASS "\n\\begin{verbatim}\n",
                                      $name , "\n\\end{verbatim}\n";
                        }
			elsif( $type eq "Ref" ) {
				my $ref = $node->{Ref};
				if ( defined $ref ) {
					print "found reference for $name\n";
					print CLASS refName( $ref );
				}
				else {
					print CLASS $name;
				}
			}
                        elsif ( $type eq "ParaBreak" ) {
                                print CLASS "\n\n";
                        }
			elsif ( $type eq "ListItem" ) {
				if ( $lasttype ne "ListItem" ) {
					print CLASS "\n\\begin{itemize}\n";
				}
				print CLASS "\\item ", 
					deref( $name, $rootnode ), "\n";
			}

			$lasttype = $type;
                }

		if( $type eq "ListItem" ) {
			print CLASS "\n\\end{itemize}\n";
		}

                print CLASS "\n\n";

        }


	# Params
	my @paramlist = ();
	kdocAstUtil::findNodes( \@paramlist, $docNode->{Text},
			"NodeType", "Param" );

	if( $#paramlist >= 0 ) {
		my $pnode;
		print CLASS "\n\n\\textbf{Parametry}:\n\n",
			"\\begin{longtable}{lp{8cm}}\n";
		
		foreach $pnode ( @paramlist ) {
			print CLASS 
                          "\\emph{", esc($pnode->{Name}), '} & ',
                          deref($pnode->{astNodeName}, $rootnode ),
                          "\\\\\n";
		}
		print CLASS "\\end{longtable}\n";
	}

	# Return
	printTextItem( $docNode, CLASS, "Returns", "Wynik" );

        my @exception_list = ();
        kdocAstUtil::findNodes( \@exception_list, $docNode->{Text},
                                "NodeType", "Throws" );
        if( $#exception_list >= 0 ) {
		my $pnode;
		print CLASS "\n\n\\textbf{Wyjątki}:\n",
			"\\begin{longtable}{lp{8cm}}\n";
		
		foreach $pnode ( @exception_list ) {
			print CLASS 
                          "\\emph{", esc($pnode->{Name}), '} & ',
                          deref($pnode->{astNodeName}, $rootnode ),
                          "\\\\\n";
		}
		print CLASS "\\end{longtable}\n";
        }

	# See
	$text = $docNode->{See};
	my $tref = $docNode->{SeeRef};
	
	if ( defined $text ) {
		my $comma = "\n\n\\textbf{Patrz też}: ";

		foreach $ctr ( 0..$#{$text} ) {
			if ( defined $tref->[ $ctr ] ) {
				print CLASS $comma, refName( $tref->[ $ctr ] );
			}
			else {
				print CLASS $comma, esc( $text->[ $ctr ] );
			}

			$comma = ", ";
		}
		print CLASS "\n\n";
	}

	return if $comp;

	printTextItem( $docNode, CLASS, "Since", "Od" );
	printTextItem( $docNode, CLASS, "Version", "Wersja" );
	printTextItem( $docNode, CLASS, "Id" );
	printTextItem( $docNode, CLASS, "Author", "Autor" );
}

=head3 printTextItem

	Parameters: node, *filehandle, prop, label

	If prop is set, it prints the label and the prop value deref()ed.

=cut

sub printTextItem
{
	local ( $node, *CLASS, $prop, $label ) = @_;
	my $text = $node->{ $prop };
	
	return unless defined $text;
	$label = $prop unless defined $label;
	
#	print CLASS "\n\n\\textbf{", $label, "}: ", deref( $text, $rootnode  ), "\n\n";
#	print CLASS "\n\n\\textbf{$label}:\n\n", deref( $text, $rootnode  ), "\n\n";
        my $txt = deref($text, $rootnode);
	print CLASS <<EOF

\\textbf{$label}:

\\begin{longtable}{lp{10cm}}
 & $txt \\\\
\\end{longtable}
EOF
}

sub textRef
{
	my ( $str, $rootnode ) = @_;
	my $word;
	my $out = "";

	foreach $word ( split( /([^\w:]+)/, $str ) ) {
		if ( $word =~ /^[^\w:]/ ) {
			$out .= esc($word);
		}
		else {
			$out .= wordRef( $word, $rootnode );
		}
	}

	return $out;
}

=head3 wordRef

	Parameters: word

	Prints a hyperlink to the word's' reference if found, otherwise
	just prints the word. Good for @refs etc.

=cut

sub wordRef
{
	my ( $str, $rootnode ) = @_;
	confess "rootnode is undef" if !defined $rootnode;

	return "" if $str eq "";

        # MK --> chcę linkować Ref'y i ConstRef'y
#	my $ref = kdocAstUtil::findRef( $rootnode, $str );
        my $str2 = $str;
        $str2 =~ s/(Const)?Ref$//;
        my $ref = kdocAstUtil::findRef( $rootnode, $str2 );

# ??? Powyższe nigdy się nie znajdzie bo jeszcze nie robię referencji. A
# hashe zostają...
        $str =~ s/^\#//;

	return esc($str) if !defined $ref;

	return hyper( $ref->{Ref}, esc($str) );
}

sub hyper
{
	confess "hyper: undefed parameter $_[0], $_[1]"
#		unless defined $_[0] && defined $_[1];
		unless defined $_[1];
#	return "<A HREF=\"$_[0]\">".esc($_[1])."</A>";
        my $result = esc($_[1]);
#        print "DIAG: hyper zwraca $result\n";
	return $result;
}


1;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic