From: Tim Jenness Date: Tue, 20 Nov 2001 11:36:54 +0000 (-1000) Subject: Pod::LaTeX up to V0.54 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1826411a4d1d01fc62c0c7f61ae006f489a962fc;p=p5sagit%2Fp5-mst-13.2.git Pod::LaTeX up to V0.54 Message-ID: p4raw-id: //depot/perl@13142 --- diff --git a/lib/Pod/LaTeX.pm b/lib/Pod/LaTeX.pm index 218714d..58a3714 100644 --- a/lib/Pod/LaTeX.pm +++ b/lib/Pod/LaTeX.pm @@ -1,8 +1,5 @@ package Pod::LaTeX; -# Copyright (C) 2000 by Tim Jenness -# All Rights Reserved. - =head1 NAME Pod::LaTeX - Convert Pod data to formatted Latex @@ -36,7 +33,7 @@ use Carp; use vars qw/ $VERSION %HTML_Escapes @LatexSections /; -$VERSION = '0.53'; +$VERSION = '0.54'; # Definitions of =headN -> latex mapping @LatexSections = (qw/ @@ -52,13 +49,17 @@ $VERSION = '0.53'; # Up to "yuml" these are taken from the original pod2latex # command written by Taro Kawagish (kawagish@imslab.co.jp) + %HTML_Escapes = ( - 'amp' => '&', # ampersand - 'lt' => '$<$', # ' left chevron, less-than - 'gt' => '$>$', # ' right chevron, greater-than + # lt, gt and verbar are inserted without math mode + # since the $$ will be added during general correction + # for those escpae characters + 'amp' => '\&', # ampersand + 'lt' => '<', # ' left chevron, less-than + 'gt' => '>', # ' right chevron, greater-than 'quot' => '"', # double quote 'sol' => '/', - 'verbar' => '$|$', + 'verbar' => '|', "Aacute" => "\\'{A}", # capital A, acute accent "aacute" => "\\'{a}", # small a, acute accent @@ -254,9 +255,7 @@ sub initialize { # Internals $self->{_Lists} = []; # For nested lists $self->{_suppress_all_para} = 0; # For =begin blocks - $self->{_suppress_next_para} = 0; # For =for blocks $self->{_dont_modify_any_para}=0; # For =begin blocks - $self->{_dont_modify_next_para}=0; # For =for blocks $self->{_CURRENT_HEAD1} = ''; # Name of current HEAD1 section # Options - only initialise if not already set @@ -370,7 +369,7 @@ In its simplest form this is simply: \end{document} -but can be more complicated if an index is required. +but can be more complicated if a index is required. Can be used to set or retrieve the current value. $add = $parser->AddPostamble(); @@ -840,13 +839,21 @@ sub command { # return if we dont care return if $command eq 'pod'; + # Store a copy of the raw text in case we are in a =for + # block and need to preserve the existing latex + my $rawpara = $paragraph; + + # Do the latex escapes $paragraph = $self->_replace_special_chars($paragraph); # Interpolate pod sequences in paragraph $paragraph = $self->interpolate($paragraph, $line_num); - $paragraph =~ s/\s+$//; + # Replace characters that can only be done after + # interpolation of interior sequences + $paragraph = $self->_replace_special_chars_late($paragraph); + # Now run the command if ($command eq 'over') { @@ -903,14 +910,24 @@ sub command { } elsif ($command eq 'for') { - # pass through if latex - if ($paragraph =~ /^latex/i) { + # =for latex + # some latex + + # With =for we will get the text for the full paragraph + # as well as the format name. + # We do not get an additional paragraph later on. The next + # paragraph is not governed by the =for + + # The first line contains the format and the rest is the + # raw code. + my ($format, $chunk) = split(/\n/, $rawpara, 2); + + # If we have got some latex code print it out immediately + # unmodified. Else do nothing. + if ($format =~ /^latex/i) { # Make sure that next paragraph is not modfied before printing - $self->{_dont_modify_next_para} = 1; + $self->_output( $chunk ); - } else { - # Suppress the next paragraph unless it is latex - $self->{_suppress_next_para} = 1 } } elsif ($command eq 'end') { @@ -939,14 +956,11 @@ sub verbatim { my $self = shift; my ($paragraph, $line_num, $parobj) = @_; - # Expand paragraph unless in =for or =begin block - if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) { + # Expand paragraph unless in =begin block + if ($self->{_dont_modify_any_para}) { # Just print as is $self->_output($paragraph); - # Reset flag if in =for - $self->{_dont_modify_next_para} = 0; - } else { return if $paragraph =~ /^\s+$/; @@ -954,8 +968,21 @@ sub verbatim { # Clean trailing space $paragraph =~ s/\s+$//; - # Clean tabs - $paragraph =~ s/\t/ /g; + # Clean tabs. Routine taken from Tabs.pm + # by David Muir Sharnoff muir@idiom.com, + # slightly modified by hsmyers@sdragons.com 10/22/01 + my @l = split("\n",$paragraph); + foreach (@l) { + 1 while s/(^|\n)([^\t\n]*)(\t+)/ + $1. $2 . (" " x + (8 * length($3) + - (length($2) % 8))) + /sex; + } + $paragraph = join("\n",@l); + # End of change. + + $self->_output('\begin{verbatim}' . "\n$paragraph\n". '\end{verbatim}'."\n"); } @@ -972,19 +999,16 @@ sub textblock { my ($paragraph, $line_num, $parobj) = @_; # print Dumper($self); - - # Expand paragraph unless in =for or =begin block - if ($self->{_dont_modify_any_para} || $self->{_dont_modify_next_para}) { + + # Expand paragraph unless in =begin block + if ($self->{_dont_modify_any_para}) { # Just print as is $self->_output($paragraph); - # Reset flag if in =for - $self->{_dont_modify_next_para} = 0; - return; - } + } + - # Escape latex special characters $paragraph = $self->_replace_special_chars($paragraph); @@ -992,6 +1016,8 @@ sub textblock { my $expansion = $self->interpolate($paragraph, $line_num); $expansion =~ s/\s+$//; + # Escape special characters that can not be done earlier + $expansion = $self->_replace_special_chars_late($expansion); # If we are replacing 'head1 NAME' with a section # we need to look in the paragraph and rewrite things @@ -1122,7 +1148,8 @@ sub interior_sequence { } elsif ($seq_command eq 'P') { # Special markup for Pod::Hyperlink - # Replace :: with / + # Replace :: with / - but not sure if I want to do this + # any more. my $link = $seq_argument; $link =~ s/::/\//g; @@ -1131,7 +1158,7 @@ sub interior_sequence { } elsif ($seq_command eq 'Q') { # Special markup for Pod::Hyperlink - return "\\textsf{$seq_argument}\n"; + return "\\textsf{$seq_argument}"; } elsif ($seq_command eq 'X') { # Index entries @@ -1242,7 +1269,7 @@ sub add_item { # If paragraphs printing is turned off via =begin/=end or whatver # simply return immediately - return if ($self->{_suppress_all_para} || $self->{_suppress_next_para}); + return if $self->{_suppress_all_para}; # Check to see whether we are starting a new lists if (scalar($self->lists->[-1]->item) == 0) { @@ -1270,12 +1297,20 @@ sub add_item { if ($type eq 'description') { # Handle long items - long items do not wrap - if (length($paragraph) < 40) { - # A real description list item - $self->_output("\\item[$paragraph] \\mbox{}"); + # If the string is longer than 40 characters we split + # it into a real item header and some bold text. + my $maxlen = 40; + my ($hunk1, $hunk2) = $self->_split_delimited( $paragraph, $maxlen ); + + # Print the first hunk + $self->_output("\n\\item[$hunk1] "); + + # and the second hunk if it is defined + if ($hunk2) { + $self->_output("\\textbf{$hunk2}"); } else { - # The item is now simply bold text - $self->_output(qq{\\item \\textbf{$paragraph}}); + # Not there so make sure we have a new line + $self->_output("\\mbox{}"); } } else { @@ -1283,7 +1318,7 @@ sub add_item { # out the something my $extra_info = $paragraph; $extra_info =~ s/^\*\s*//; - $self->_output("\\item $extra_info"); + $self->_output("\n\\item $extra_info"); } # Store the item name in the object. Required so that @@ -1344,7 +1379,7 @@ sub head { my $star = ($level >= $self->LevelNoNum ? '*' : ''); # Section - $self->_output("\\" .$LatexSections[$level] .$star ."{$paragraph\\label{".$label ."}\\index{".$index."}}"); + $self->_output("\\" .$LatexSections[$level] .$star ."{$paragraph\\label{".$label ."}\\index{".$index."}}\n"); } @@ -1369,7 +1404,7 @@ to output parsed text. $parser->_output($text); -Does not write anything if a =begin or =for is active that should be +Does not write anything if a =begin is active that should be ignored. =cut @@ -1378,13 +1413,9 @@ sub _output { my $self = shift; my $text = shift; - print { $self->output_handle } $text - unless $self->{_suppress_all_para} || - $self->{_suppress_next_para}; + print { $self->output_handle } $text + unless $self->{_suppress_all_para}; - # Reset pargraph stuff for =for - $self->{_suppress_next_para} = 0 - if $self->{_suppress_next_para}; } @@ -1395,8 +1426,12 @@ with the escaped forms $escaped = $parser->_replace_special_chars($paragraph); -Need to call this routine before interior_sequences are munged but -not if verbatim. +Need to call this routine before interior_sequences are munged but not +if verbatim. It must be called before interpolation of interior +sequences so that curly brackets and special latex characters inserted +during interpolation are not themselves escaped. This means that < and +> can not be modified here since the text still contains interior +sequences. Special characters and the C equivalents are: @@ -1409,7 +1444,6 @@ Special characters and the C equivalents are: \ $\backslash$ ^ \^{} ~ \~{} - | $|$ =cut @@ -1433,11 +1467,37 @@ sub _replace_special_chars { # Replace tilde (~) with \texttt{\~{}} $paragraph =~ s/~/\\texttt\{\\~\{\}\}/g; + # Now add the dollars around each \backslash + $paragraph =~ s/(\\backslash)/\$$1\$/g; + return $paragraph; +} + +=item B<_replace_special_chars_late> + +Replace special characters that can not be replaced before interior +sequence interpolation. See C<_replace_special_chars> for a routine +to replace special characters prior to interpolation of interior +sequences. + +Does the following transformation: + + < $<$ + > $>$ + | $|$ + + +=cut + +sub _replace_special_chars_late { + my $self = shift; + my $paragraph = shift; + + # < and > + $paragraph =~ s/(<|>)/\$$1\$/g; + # Replace | with $|$ $paragraph =~ s'\|'$|$'g; - # Now add the dollars around each \backslash - $paragraph =~ s/(\\backslash)/\$$1\$/g; return $paragraph; } @@ -1551,6 +1611,66 @@ sub _clean_latex_commands { return $paragraph } +=item B<_split_delimited> + +Split the supplied string into two parts at approximately the +specified word boundary. Special care is made to make sure that it +does not split in the middle of some curly brackets. + +e.g. "this text is \textbf{very bold}" would not be split into +"this text is \textbf{very" and " bold". + + ($hunk1, $hunk2) = $self->_split_delimited( $para, $length); + +The length indicates the maximum length of hunk1. + +=cut + +# initially Supplied by hsmyers@sdragons.com +# 10/25/01, utility to split \hbox +# busting lines. Reformatted by TimJ to match module style. +sub _split_delimited { + my $self = shift; + my $input = shift; + my $limit = shift; + + # Return immediately if already small + return ($input, '') if length($input) < $limit; + + my @output; + my $s = ''; + my $t = ''; + my $depth = 0; + my $token; + + $input =~ s/\n/ /gm; + $input .= ' '; + foreach ( split ( //, $input ) ) { + $token .= $_; + if (/\{/) { + $depth++; + } elsif ( /}/ ) { + $depth--; + } elsif ( / / and $depth == 0) { + push @output, $token if ( $token and $token ne ' ' ); + $token = ''; + } + } + + foreach (@output) { + if (length($s) < $limit) { + $s .= $_; + } else { + $t .= $_; + } + } + + # Tidy up + $s =~ s/\s+$//; + $t =~ s/\s+$//; + return ($s,$t); +} + =back =end __PRIVATE__ @@ -1573,18 +1693,24 @@ L, L, L Tim Jenness Et.jenness@jach.hawaii.eduE +Bug fixes have been received from: Simon Cozens +Esimon@cozens.netE, Mark A. Hershberger +Emah@everybody.orgE, Marcel Grunauer +Emarcel@codewerk.comE and Hugh S Myers +Ehsmyers@sdragons.comE. + =head1 COPYRIGHT -Copyright (C) 2000 Tim Jenness. All Rights Reserved. +Copyright (C) 2000-2001 Tim Jenness. All Rights Reserved. -This program is free software; you can redistribute it and/or modify it -under the same terms as Perl itself. +This program is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. =begin __PRIVATE__ =head1 REVISION -$Id: LaTeX.pm,v 1.6 2000/08/21 09:05:03 timj Exp $ +$Id: LaTeX.pm,v 1.12 2001/11/20 20:59:26 timj Exp $ =end __PRIVATE__ diff --git a/pod/pod2latex.PL b/pod/pod2latex.PL index 3d3cfb6..002f06d 100644 --- a/pod/pod2latex.PL +++ b/pod/pod2latex.PL @@ -37,12 +37,15 @@ print OUT <<'!NO!SUBS!'; # pod2latex conversion program +use strict; use Pod::LaTeX; use Pod::Find qw/ pod_find /; use Pod::Usage; use Getopt::Long; use File::Basename; +my $VERSION = "1.00"; + # Read command line arguments my %options = ( @@ -53,6 +56,7 @@ my %options = ( "out" => undef, "verbose" => 0, "modify" => 0, + "h1level" => 1, # section is equivalent to H1 ); GetOptions(\%options, @@ -63,6 +67,7 @@ GetOptions(\%options, "sections=s@", "out=s", "modify", + "h1level=i", ) || pod2usage(2); pod2usage(1) if ($options{help}); @@ -126,6 +131,8 @@ if ($multi_documents) { TableOfContents => $options{'full'}, ReplaceNAMEwithSection => $options{'modify'}, UniqueLabels => $options{'modify'}, + Head1Level => $options{'h1level'}, + LevelNoNum => $options{'h1level'} + 1, ); # Select sections if supplied @@ -173,11 +180,8 @@ if ($multi_documents) { # if this is the first file to be converted we may want to add # a preamble (controlled by command line option) - if ($converted == 0 && $options{'full'}) { - $preamble = 1; - } else { - $preamble = 0; - } + my $preamble = 0; + $preamble = 1 if ($converted == 0 && $options{'full'}); # if this is the last file to be converted may want to add # a postamble (controlled by command line option) @@ -196,6 +200,8 @@ if ($multi_documents) { StartWithNewPage => $options{'full'}, AddPreamble => $preamble, AddPostamble => $postamble, + Head1Level => $options{'h1level'}, + LevelNoNum => $options{'h1level'} + 1, ); # Store the file name for error messages @@ -294,6 +300,13 @@ which is helpful for including module descriptions in documentation. Also forces C label and index entries to be prefixed by the name of the module. +=item B<-h1level> + +Specifies the C section that is equivalent to a C

pod +directive. This is an integer between 0 and 5 with 0 equivalent to a +C chapter, 1 equivalent to a C section etc. The default +is 1 (C

equivalent to a latex section). + =item B<-help> Print a brief help message and exit.