X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=doc%2Ftexi2pod.pl;h=3fe0b8f12d7241133d5ff3d833370eb1b6793b88;hp=fcf910d232f40c4a511f9904e7de055bc88c49bd;hb=4198c7239f11f85002798dd4fce4f0bc1042547a;hpb=18d476b8d013cdc117a376c840bb00ccd32c2798 diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl old mode 100644 new mode 100755 index fcf910d2..3fe0b8f1 --- a/doc/texi2pod.pl +++ b/doc/texi2pod.pl @@ -1,9 +1,29 @@ -#! /usr/bin/perl -w +#! /usr/bin/env perl + +# Copyright (C) 1999, 2000, 2001, 2003, 2007 Free Software +# Foundation, Inc. + +# This file is part of GCC. + +# GCC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. + +# GCC is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with GCC. If not, see . # This does trivial (and I mean _trivial_) conversion of Texinfo # markup to Perl POD format. It's intended to be used to extract # something suitable for a manpage from a Texinfo document. +use warnings; + $output = 0; $skipping = 0; %sects = (); @@ -11,9 +31,12 @@ $section = ""; @icstack = (); @endwstack = (); @skstack = (); +@instack = (); $shift = ""; %defs = (); $fnno = 1; +$inf = ""; +$ibase = ""; while ($_ = shift) { if (/^-D(.*)$/) { @@ -22,11 +45,13 @@ while ($_ = shift) { } else { $flag = shift; } + $value = ""; + ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/); die "no flag specified for -D\n" unless $flag ne ""; - die "flags may only contain letters, digits, hyphens, and underscores\n" + die "flags may only contain letters, digits, hyphens, dashes and underscores\n" unless $flag =~ /^[a-zA-Z0-9_-]+$/; - $defs{$flag} = ""; + $defs{$flag} = $value; } elsif (/^-/) { usage(); } else { @@ -37,14 +62,19 @@ while ($_ = shift) { } if (defined $in) { - open(STDIN, $in) or die "opening \"$in\": $!\n"; + $inf = gensym(); + open($inf, "<$in") or die "opening \"$in\": $!\n"; + $ibase = $1 if $in =~ m|^(.+)/[^/]+$|; +} else { + $inf = \*STDIN; } + if (defined $out) { open(STDOUT, ">$out") or die "opening \"$out\": $!\n"; } -while() -{ +while(defined $inf) { +while(<$inf>) { # Certain commands are discarded without further processing. /^\@(?: [a-z]+index # @*index: useful only in complete manual @@ -52,25 +82,51 @@ while() |(?:end\s+)?group # @group .. @end group: ditto |page # @page: ditto |node # @node: useful only in .info file + |(?:end\s+)?ifnottex # @ifnottex .. @end ifnottex: use contents )\b/x and next; - + chomp; # Look for filename and title markers. /^\@setfilename\s+([^.]+)/ and $fn = $1, next; - /^\@settitle\s+([^.]+)/ and $tl = $1, next; + /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next; + + # Identify a man title but keep only the one we are interested in. + /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do { + if (exists $defs{$1}) { + $fn = $1; + $tl = postprocess($2); + } + next; + }; # Look for blocks surrounded by @c man begin SECTION ... @c man end. # This really oughta be @ifman ... @end ifman and the like, but such # would require rev'ing all other Texinfo translators. - /^\@c man begin ([A-Z]+)/ and $sect = $1, $output = 1, next; - /^\@c man end/ and do { + /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do { + $output = 1 if exists $defs{$2}; + $sect = $1; + next; + }; + /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next; + /^\@c\s+man\s+end/ and do { $sects{$sect} = "" unless exists $sects{$sect}; $sects{$sect} .= postprocess($section); $section = ""; $output = 0; next; }; + + # handle variables + /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do { + $defs{$1} = $2; + next; + }; + /^\@clear\s+([a-zA-Z0-9_-]+)/ and do { + delete $defs{$1}; + next; + }; + next unless $output; # Discard comments. (Can't do it above, because then we'd never see @@ -83,20 +139,20 @@ while() # Ignore @end foo, where foo is not an operation which may # cause us to skip, if we are presently skipping. my $ended = $1; - next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu)$/; + next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex|copying)$/; die "\@end $ended without \@$ended at line $.\n" unless defined $endw; die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw; $endw = pop @endwstack; - if ($ended =~ /^(?:ifset|ifclear|ignore|menu)$/) { + if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) { $skipping = pop @skstack; next; - } elsif ($ended =~ /^(?:example|smallexample)$/) { + } elsif ($ended =~ /^(?:example|smallexample|display)$/) { $shift = ""; $_ = ""; # need a paragraph break - } elsif ($ended =~ /^(?:itemize|enumerate|table)$/) { + } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) { $_ = "\n=back\n"; $ic = pop @icstack; } else { @@ -123,7 +179,7 @@ while() next; }; - /^\@(ignore|menu)\b/ and do { + /^\@(ignore|menu|iftex|copying)\b/ and do { push @endwstack, $endw; push @skstack, $skipping; $endw = $1; @@ -144,13 +200,20 @@ while() s/\@TeX\{\}/TeX/g; s/\@pounds\{\}/\#/g; s/\@minus(?:\{\})?/-/g; + s/\\,/,/g; # Now the ones that have to be replaced by special escapes # (which will be turned back into text by unmunge()) s/&/&/g; + s/\@\@/&at;/g; s/\@\{/{/g; s/\@\}/}/g; - s/\@\@/&at;/g; + + # Inside a verbatim block, handle @var specially. + if ($shift ne "") { + s/\@var\{([^\}]*)\}/<$1>/g; + } + # POD doesn't interpret E<> inside a verbatim block. if ($shift eq "") { s/) } # Single line command handlers. - /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and $defs{$1} = $2, next; - /^\@clear\s+([a-zA-Z0-9_-]+)/ and delete $defs{$1}, next; - /^\@section\s+(.+)$/ and $_ = "\n=head2 $1\n"; - /^\@subsection\s+(.+)$/ and $_ = "\n=head3 $1\n"; + /^\@include\s+(.+)$/ and do { + push @instack, $inf; + $inf = gensym(); + $file = postprocess($1); + + # Try cwd and $ibase. + open($inf, "<" . $file) + or open($inf, "<" . $ibase . "/" . $file) + or die "cannot open $file or $ibase/$file: $!\n"; + next; + }; + + /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/ + and $_ = "\n=head2 $1\n"; + /^\@subsection\s+(.+)$/ + and $_ = "\n=head3 $1\n"; # Block command handlers: - /^\@itemize\s+(\@[a-z]+|\*|-)/ and do { + /^\@itemize(?:\s+(\@[a-z]+|\*|-))?/ and do { push @endwstack, $endw; push @icstack, $ic; - $ic = $1; + if (defined $1) { + $ic = $1; + } else { + $ic = '@bullet'; + } $_ = "\n=over 4\n"; $endw = "itemize"; }; - /^\@enumerate(?:\s+([A-Z0-9]+))?/ and do { + /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do { push @endwstack, $endw; push @icstack, $ic; if (defined $1) { @@ -188,19 +267,19 @@ while() $endw = "enumerate"; }; - /^\@table\s+(\@[a-z]+)/ and do { + /^\@([fv]?table)\s+(\@[a-z]+)/ and do { push @endwstack, $endw; push @icstack, $ic; - $ic = $1; - $ic =~ s/\@(?:samp|strong|key)/B/; + $endw = $1; + $ic = $2; + $ic =~ s/\@(?:samp|strong|key|gcctabopt|env)/B/; $ic =~ s/\@(?:code|kbd)/C/; $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/; $ic =~ s/\@(?:file)/F/; $_ = "\n=over 4\n"; - $endw = "table"; }; - /^\@((?:small)?example)/ and do { + /^\@((?:small)?example|display)/ and do { push @endwstack, $endw; $endw = $1; $shift = "\t"; @@ -209,27 +288,38 @@ while() /^\@itemx?\s*(.+)?$/ and do { if (defined $1) { - # Entity escapes prevent munging by the <> processing below. - $_ = "\n=item $ic\<$1\>\n"; + my $thing = $1; + if ($ic =~ /\@asis/) { + $_ = "\n=item $thing\n"; + } else { + # Entity escapes prevent munging by the <> processing below. + $_ = "\n=item $ic\<$thing\>\n"; + } } else { $_ = "\n=item $ic\n"; - $ic =~ y/A-Ya-y1-8/B-Zb-z2-9/; + $ic =~ y/A-Ya-y/B-Zb-z/; + $ic =~ s/(\d+)/$1 + 1/eg; } }; $section .= $shift.$_."\n"; } +# End of current file. +close($inf); +$inf = pop @instack; +} die "No filename or title\n" unless defined $fn && defined $tl; $sects{NAME} = "$fn \- $tl\n"; $sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES}; -for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES - BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) { +for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT EXITSTATUS + FILES BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) { if(exists $sects{$sect}) { $head = $sect; $head =~ s/SEEALSO/SEE ALSO/; + $head =~ s/EXITSTATUS/EXIT STATUS/; print "=head1 $head\n\n"; print scalar unmunge ($sects{$sect}); print "\n"; @@ -246,47 +336,66 @@ sub postprocess local $_ = $_[0]; # @value{foo} is replaced by whatever 'foo' is defined as. - s/\@value\{([a-zA-Z0-9_-]+)\}/$defs{$1}/g; + while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) { + if (! exists $defs{$2}) { + print STDERR "Option $2 not defined\n"; + s/\Q$1\E//; + } else { + $value = $defs{$2}; + s/\Q$1\E/$value/; + } + } # Formatting commands. + # Temporary escape for @r. + s/\@r\{([^\}]*)\}/R<$1>/g; s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g; s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g; - s/\@(?:samp|strong|key|option|env|b)\{([^\}]*)\}/B<$1>/g; + s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g; s/\@sc\{([^\}]*)\}/\U$1/g; s/\@file\{([^\}]*)\}/F<$1>/g; s/\@w\{([^\}]*)\}/S<$1>/g; s/\@(?:dmn|math)\{([^\}]*)\}/$1/g; + # keep references of the form @ref{...}, print them bold + s/\@(?:ref)\{([^\}]*)\}/B<$1>/g; + + # Change double single quotes to double quotes. + s/''/"/g; + s/``/"/g; + # Cross references are thrown away, as are @noindent and @refill. # (@noindent is impossible in .pod, and @refill is unnecessary.) # @* is also impossible in .pod; we discard it and any newline that - # follows it. - - s/\@xref\{(?:[^\}]*)\}[^.]*.//g; - - # Originally "s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;", would not - # process cross-references like '(@pxref{some section} for more - # details)" - s/\s+\(\@pxref\{(?:[^\}]*)\}[^\)]*\)//g; + # follows it. Similarly, our macro @gol must be discarded. + s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g; + s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g; s/;\s+\@pxref\{(?:[^\}]*)\}//g; s/\@noindent\s*//g; s/\@refill//g; + s/\@gol//g; s/\@\*\s*\n?//g; # @uref can take one, two, or three arguments, with different # semantics each time. @url and @email are just like @uref with # one argument, for our purposes. - s/\@(?:uref|url|email)\{([^\},]*)\}/<C<$1>>/g; + s/\@(?:uref|url|email)\{([^\},]*)\}/<B<$1>>/g; s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g; s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g; - # Turn B blah> into B I B to - # match Texinfo semantics of @emph inside @samp. + # Un-escape <> at this point. s/<//g; - 1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B]*)B<([^>]+)>/I<$1>B<$2>I, I<>, R<>. Theoretically we could have + # indefinitely deep nesting; in practice, one level suffices. + 1 while s/([BIR])<([^<>]*)([BIR])<([^<>]*)>/$1<$2>$3<$4>$1 with bare ...; eliminate empty markup, B<>; + # shift white space at the ends of [BI]<...> expressions outside + # the expression. + s/R<([^<>]*)>/$1/g; s/[BI]<>//g; s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g; s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g; @@ -327,5 +436,15 @@ sub add_footnote $sects{FOOTNOTES} .= $_[0]; $sects{FOOTNOTES} .= "\n\n"; } - +# stolen from Symbol.pm +{ + my $genseq = 0; + sub gensym + { + my $name = "GEN" . $genseq++; + my $ref = \*{$name}; + delete $::{$name}; + return $ref; + } +}