diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2000-02-22 17:10:22 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2000-02-22 17:10:22 +0000 |
commit | d3a4b2ba6901538e050a5a3fced30a16ff8fb9b0 (patch) | |
tree | 6a9ea92eb1a04fc898f4eb6457c778bf1cc1b7c5 /lib/Pod/Parser.pm | |
parent | 68435ea717a7cd7f41241ff44917b542abd94222 (diff) | |
parent | da2094fd55cfc73caee2f71b349588c60a542297 (diff) | |
download | perl-d3a4b2ba6901538e050a5a3fced30a16ff8fb9b0.tar.gz |
Integrate with Sarathy.
p4raw-id: //depot/cfgperl@5203
Diffstat (limited to 'lib/Pod/Parser.pm')
-rw-r--r-- | lib/Pod/Parser.pm | 118 |
1 files changed, 76 insertions, 42 deletions
diff --git a/lib/Pod/Parser.pm b/lib/Pod/Parser.pm index c727142506..bafabba093 100644 --- a/lib/Pod/Parser.pm +++ b/lib/Pod/Parser.pm @@ -1,7 +1,7 @@ ############################################################################# # Pod/Parser.pm -- package which defines a base class for parsing POD docs. # -# Copyright (C) 1996-1999 by Bradford Appleton. All rights reserved. +# Copyright (C) 1996-2000 by Bradford Appleton. All rights reserved. # This file is part of "PodParser". PodParser is free software; # you can redistribute it and/or modify it under the same terms # as Perl itself. @@ -10,7 +10,7 @@ package Pod::Parser; use vars qw($VERSION); -$VERSION = 1.091; ## Current version of this package +$VERSION = 1.093; ## Current version of this package require 5.004; ## requires this Perl version or later ############################################################################# @@ -55,9 +55,9 @@ Pod::Parser - base class for creating POD filters and translators sub interior_sequence { my ($parser, $seq_command, $seq_argument) = @_; ## Expand an interior sequence; sample actions might be: - return "*$seq_argument*" if ($seq_command = 'B'); - return "`$seq_argument'" if ($seq_command = 'C'); - return "_${seq_argument}_'" if ($seq_command = 'I'); + return "*$seq_argument*" if ($seq_command eq 'B'); + return "`$seq_argument'" if ($seq_command eq 'C'); + return "_${seq_argument}_'" if ($seq_command eq 'I'); ## ... other sequence commands and their resulting text } @@ -142,8 +142,8 @@ For the most part, the B<Pod::Parser> base class should be able to do most of the input parsing for you and leave you free to worry about how to intepret the commands and translate the result. -Note that all we have described here in this quick overview is -the simplest most straightforward use of B<Pod::Parser> to do stream-based +Note that all we have described here in this quick overview is the +simplest most straightforward use of B<Pod::Parser> to do stream-based parsing. It is also possible to use the B<Pod::Parser::parse_text> function to do more sophisticated tree-based parsing. See L<"TREE-BASED PARSING">. @@ -599,7 +599,7 @@ Please note that the B<preprocess_line()> method is invoked I<before> the B<preprocess_paragraph()> method. After all (possibly preprocessed) lines in a paragraph have been assembled together and either it has been determined that the paragraph is part of the POD documentation from one -of the selected sections or the C<-want_nonPODs> option is true, +of the selected sections or the C<-want_nonPODs> option is true, then B<preprocess_paragraph()> is invoked. The base class implementation of this method returns the given text. @@ -718,13 +718,6 @@ is a reference to the parse-tree object. =cut -## This global regex is used to see if the text before a '>' inside -## an interior sequence looks like '-' or '=', but not '--', '==', -## '!=', '$-', '$=' or <<op>>= -use vars qw( $ARROW_RE ); -$ARROW_RE = join('', qw{ (?: [^-+*/=!&|%^x.<>$]= | [^-$]- )$ }); -#$ARROW_RE = qr/(?:[^-+*/=!&|%^x.<>$]+=|[^-$]+-)$/; ## 5.005+ only! - sub parse_text { my $self = shift; local $_ = ''; @@ -738,7 +731,7 @@ sub parse_text { my $text = shift; my $line = shift; my $file = $self->input_file(); - my ($cmd, $prev) = ('', ''); + my $cmd = ""; ## Convert method calls into closures, for our convenience my $xseq_sub = $expand_seq; @@ -757,7 +750,7 @@ sub parse_text { ref $xseq_sub or $xseq_sub = sub { shift()->$expand_seq(@_) }; ref $xtext_sub or $xtext_sub = sub { shift()->$expand_text(@_) }; ref $xptree_sub or $xptree_sub = sub { shift()->$expand_ptree(@_) }; - + ## Keep track of the "current" interior sequence, and maintain a stack ## of "in progress" sequences. ## @@ -769,52 +762,82 @@ sub parse_text { ## my $seq = Pod::ParseTree->new(); my @seq_stack = ($seq); + my ($ldelim, $rdelim) = ('', ''); ## Iterate over all sequence starts/stops, newlines, & text ## (NOTE: split with capturing parens keeps the delimiters) $_ = $text; - for ( split /([A-Z]<|>|\n)/ ) { - ## Keep track of line count - ++$line if ($_ eq "\n"); - ## Look for the beginning of a sequence - if ( /^([A-Z])(<)$/ ) { + my @tokens = split /([A-Z]<(?:<+\s+)?)/; + while ( @tokens ) { + $_ = shift @tokens; + ## Look for the beginning of a sequencd + if ( /^([A-Z])(<(?:<+\s+)?)$/ ) { ## Push a new sequence onto the stack of those "in-progress" + ($cmd, $ldelim) = ($1, $2); $seq = Pod::InteriorSequence->new( - -name => ($cmd = $1), - -ldelim => $2, -rdelim => '', - -file => $file, -line => $line + -name => $cmd, + -ldelim => $ldelim, -rdelim => '', + -file => $file, -line => $line ); + $ldelim =~ s/\s+$//, ($rdelim = $ldelim) =~ tr/</>/; (@seq_stack > 1) and $seq->nested($seq_stack[-1]); push @seq_stack, $seq; } - ## Look for sequence ending (preclude '->' and '=>' inside C<...>) - elsif ( (@seq_stack > 1) and - /^>$/ and ($cmd ne 'C' or $prev !~ /$ARROW_RE/o) ) - { - ## End of current sequence, record terminating delimiter - $seq->rdelim($_); - ## Pop it off the stack of "in progress" sequences - pop @seq_stack; - ## Append result to its parent in current parse tree - $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq) : $seq); - ## Remember the current cmd-name - $cmd = (@seq_stack > 1) ? $seq_stack[-1]->name : ''; + ## Look for sequence ending + elsif ( @seq_stack > 1 ) { + ## Make sure we match the right kind of closing delimiter + my ($seq_end, $post_seq) = ("", ""); + if ( ($ldelim eq '<' and /\A(.*?)(>)/s) + or /\A(.*?)(\s+$rdelim)/s ) + { + ## Found end-of-sequence, capture the interior and the + ## closing the delimiter, and put the rest back on the + ## token-list + $post_seq = substr($_, length($1) + length($2)); + ($_, $seq_end) = ($1, $2); + (length $post_seq) and unshift @tokens, $post_seq; + } + if (length) { + ## In the middle of a sequence, append this text to it, and + ## dont forget to "expand" it if that's what the caller wanted + $seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_); + $_ .= $seq_end; + } + if (length $seq_end) { + ## End of current sequence, record terminating delimiter + $seq->rdelim($seq_end); + ## Pop it off the stack of "in progress" sequences + pop @seq_stack; + ## Append result to its parent in current parse tree + $seq_stack[-1]->append($expand_seq ? &$xseq_sub($self,$seq) + : $seq); + ## Remember the current cmd-name and left-delimiter + $cmd = (@seq_stack > 1) ? $seq_stack[-1]->name : ''; + $ldelim = (@seq_stack > 1) ? $seq_stack[-1]->ldelim : ''; + $ldelim =~ s/\s+$//, ($rdelim = $ldelim) =~ tr/</>/; + } } elsif (length) { ## In the middle of a sequence, append this text to it, and ## dont forget to "expand" it if that's what the caller wanted $seq->append($expand_text ? &$xtext_sub($self,$_,$seq) : $_); } - ## Remember the "current" sequence and the previously seen token - ($seq, $prev) = ( $seq_stack[-1], $_ ); + ## Keep track of line count + $line += tr/\n//; + ## Remember the "current" sequence + $seq = $seq_stack[-1]; } ## Handle unterminated sequences my $errorsub = (@seq_stack > 1) ? $self->errorsub() : undef; while (@seq_stack > 1) { ($cmd, $file, $line) = ($seq->name, $seq->file_line); + $ldelim = $seq->ldelim; + ($rdelim = $ldelim) =~ tr/</>/; + $rdelim =~ s/^(\S+)(\s*)$/$2$1/; pop @seq_stack; - my $errmsg = "** Unterminated $cmd<...> at $file line $line\n"; + my $errmsg = "*** WARNING: unterminated ${cmd}${ldelim}...${rdelim}". + " at line $line in file $file\n"; (ref $errorsub) and &{$errorsub}($errmsg) or (defined $errorsub) and $self->$errorsub($errmsg) or warn($errmsg); @@ -1034,9 +1057,20 @@ sub parse_from_filehandle { ++$plines; } - ## See of this line is blank and ends the current paragraph. + ## See if this line is blank and ends the current paragraph. ## If it isnt, then keep iterating until it is. - next unless (($textline =~ /^\s*$/) && (length $paragraph)); + next unless (($textline =~ /^(\s*)$/) && (length $paragraph)); + + ## Issue a warning about any non-empty blank lines + if ( length($1) > 1 ) { + my $errorsub = $self->errorsub(); + my $file = $self->input_file(); + my $errmsg = "*** WARNING: line containing nothing but whitespace". + " in paragraph at line $nlines in file $file\n"; + (ref $errorsub) and &{$errorsub}($errmsg) + or (defined $errorsub) and $self->$errorsub($errmsg) + or warn($errmsg); + } ## Now process the paragraph parse_paragraph($self, $paragraph, ($nlines - $plines) + 1); |